C 在运行时检测ARMv8 A53与A57体系结构?

C 在运行时检测ARMv8 A53与A57体系结构?,c,cpu-architecture,arm64,C,Cpu Architecture,Arm64,我正在对一个库与ARMv8机器进行基准测试。我有四个Cortex-A53开发板,我们的NEON intrinsics实现比C/C++实现的性能高出约30%。这是意料之中的 GCC编译场提供Softiron Overdrive 1000。它是Cortex-A57服务器板,C/C++代码的性能比intrinsics实现高出50%。这是令人惊讶的 我们希望将NEON实现用于A-53,但将C/C++实现用于A57。我们有可以选择运行时功能的代码,比如hasnone(),HasCRC(),HasAES()

我正在对一个库与ARMv8机器进行基准测试。我有四个Cortex-A53开发板,我们的NEON intrinsics实现比C/C++实现的性能高出约30%。这是意料之中的

GCC编译场提供Softiron Overdrive 1000。它是Cortex-A57服务器板,C/C++代码的性能比intrinsics实现高出50%。这是令人惊讶的

我们希望将NEON实现用于A-53,但将C/C++实现用于A57。我们有可以选择运行时功能的代码,比如
hasnone()
HasCRC()
HasAES()
hasha()
。我们没有任何关于架构的东西,比如A53和A57

我的问题是,我们如何在运行时检测A53和A57


对于P4处理器的x86代码路径,我们有类似的代码。P4有一些缓慢的字操作。我们通过检查CPUID位来检测P4,但ARM系统不同。ARM系统类CPUID指令读取MSR,通常需要更高的权限级别(EL1或更高)


如果有兴趣,Cortex-A57对于特定的散列算法来说速度较慢,因为它严重依赖移位、旋转和异或。这告诉我们换档和旋转更昂贵。在ASIMD协处理器中,移位需要4或5个周期,只有F1管道可以执行操作(根据第3.14节)

也可能是Cortex-A53有相同的惩罚,其整数单位较慢,因此非NEON代码的性能不会优于NEON代码。

有一个
tune()
函数,该函数在进程初始化期间调用,用于对您的实现和GCC的实现进行基准测试,并缓存结果(例如,在
bool isMyImplementationFaster
全局变量中)


如果您的实现速度更快,您可以假定它是A53(如果速度较慢,您可以假定它是A57)。请注意,这会导致既不是A53也不是A57的CPU(包括未来的CPU)出现问题/混乱。但是,我希望您会意识到,您实际上并不关心它是A53还是A57(或其他),并且您只关心您的实现是否更快/更慢。

正如您和其他人所指出的,一般来说,用户模式代码无法提供真正的类cpuid指令。实际上,相关信息是以特定于平台的方式处理的

在linux上,您可以尝试解析/proc/cpuinfo(如果可用/可读)。CPU实现者/architecture/variant/part编号应该很好地标识不同的CPU。该文件在Android上也应该可读

对于其他操作系统,操作系统需要在某处提供必要的信息,而不是所有操作系统都需要

编辑: 我看到的Cortex-A53在
/proc/cpuinfo
中有以下信息:

CPU implementer : 0x41
CPU architecture: 8
CPU variant     : 0x0
CPU part        : 0xd03
而Cortex-A57具备以下功能:

CPU implementer : 0x41
CPU architecture: 8
CPU variant     : 0x1
CPU part        : 0xd07
然而,正如Brendan指出的那样,随着不同的单个内核数量不断增加,试图匹配这些内核是非常徒劳的


此外,一些SOC有一组异构的内核,请参阅。例如,Snapdragon 810有4个Cortex-A53内核和4个Cortex-A57内核。您的线程将在内核调度器认为合适的情况下在这些内核之间调度和移动。在这种情况下,启动时获得的基准编号可能与代码最终调度的内核不匹配t稍后。

您使用哪个操作系统?因为ARM上的用户程序没有CPUID。@fsasm-我们是一个免费/开源项目,所以它是一个聚宝盆…Android、Debian、FreeBSD、Linaro、Ubuntu…我最近做了一个改动,只是在Cortex-A53和A57上禁用NEON。但我真的想通过禁用NEON代码路径来修复它r A57在运行时。另请参阅。在您的自定义操作系统中,您是否有类似cat/proc/cpuinfo的东西?可能是一个无关紧要的离题问题-但您是否排除了编译器的差异?如果我没记错的话,GCC编译场Softiron机器默认为GCC 4.8,它具有许多Neon内部函数的…次优…实现。检查代码由编译器生成可能很有用,您可能会发现一些适用于AArch32的习惯用法生成的指令比使用AArch64编译器生成的指令要多。谢谢Brendan。有一个有问题的用例:发行版。它们将以“最小”的价格打包库但是,我们也包括了全功能的代码路径。例如,将有一个SHA的C++实现,一个NEN实现的SHA,以及一个使用ARMV8加密的实现。SHA很容易被检测出来,因为我们可以探测CPU并捕获一个<代码> Sigial。CordX-A53与A57比较棘手。我们不知道CPU探针要做什么。t、 @jww:这有什么问题吗?
tune
函数应该只在两个代码路径都可用的情况下在两个代码路径之间进行选择;如果打包程序只包含一个代码路径(A53或A57),那么运行时调优就没有意义了。@jww:任何差异(包括基准性能差异)是一个CPU探测器。@jww:也许我太狡猾了:你正在为自己设置失败。现在总共有18个“ARMv8-a”内核(A53和A57只是其中的2个),并且这一数量正在以每年大约4个的速度增长(基于2016年)。每个二进制测试(例如,如果
SIGILL
发生或不发生)最多只能使可能性减半。您可以使用所需的信息(指令是否受支持,序列是否更快/更慢)以错误和损坏的方式推断出不需要的无用信息(具体是哪个内核),然后使用无用/坏/损坏的信息“重新推断”您开始使用的信息。@jww:还请注意,我怀疑您可能混淆了这一问题,将两个不同的东西混为一谈——“分发时”或“编译时”优化(例如,应该由预处理器/条件代码控制-例如
#ifdef ARCH_A53
)和“运行时”优化(需要运行时测试).如果是这样,那么我的