在运行时检测 ARMv8 A53 与 A57 架构?
Detect ARMv8 A53 vs A57 architecture at runtime?
我正在针对 ARMv8 机器对库进行基准测试。我有四个 Cortex-A53 开发板,我们的 NEON 内在函数实现比 C/C++ 实现高出大约 30%。这是预期的。
GCC compile farm 提供了一个 Softiron Overdrive 1000。它是一个 Cortex-A57 服务器主板,C/C++ 代码比内部函数实现高出 50%。这真是令人惊讶。
我们想对 A-53 使用我们的 NEON 实现,但对 A57 使用 C/C++ 实现。我们有可以进行运行时特征选择的代码,例如 HasNEON()
、HasCRC()
、HasAES()
和 HasSHA()
。我们没有关于架构的任何信息,例如 A53 与 A57。
我的问题是,我们如何在运行时检测 A53 与 A57?
我们为 P4 处理器的 x86 代码路径提供了类似的代码。 P4 有一些慢字操作。我们通过检查 CPUID 位来检测 P4,但是 ARM 系统不同。 ARM系统类CPUID指令读取MSR,通常需要更高的权限级别(EL1或以上)。
如果有兴趣,Cortex-A57 对于特定的哈希算法来说速度较慢,因为它严重依赖于移位、旋转和异或运算。 A57 Optimization guide 告诉我们移位和旋转更昂贵。在 ASIMD 协处理器中需要 4 或 5 个周期进行移位,并且只有 F1 管道可以执行操作(根据第 3.14 节)。
也可能是 Cortex-A53 有同样的惩罚,它的整数单元更慢,所以非 NEON 代码没有优于 NEON 代码。
有一个在进程初始化期间调用的 tune()
函数,它对您的实现和 GCC 的实现进行基准测试并缓存结果(例如,在 bool isMyImplementationFaster
全局变量中)。
如果您的实现速度更快,您可以假设它是 A53(如果它更慢,您可以假设它是 A57)。请注意,对于既不是 A53 也不是 A57 的 CPU(包括未来的 CPU),这会导致 problem/confusion。然而;我希望你会意识到你实际上并不关心它是 A53 还是 A57(或其他东西),你只关心你的实现是 faster/slower.
一般来说,正如您和其他人所指出的,真正的 cpuid-like 指令在用户模式代码中不可用。实际上,相关信息以特定于平台的方式处理。
在 linux 上,您可以尝试解析 /proc/cpuinfo,如果 available/readable。 CPU implementer/architecture/variant/part 数字应该很好地识别不同的 CPU。此文件应在 Android.
上也可读 IIRC
对于其他 OSes,OS 需要在某处提供必要的信息,但并非所有信息都可能提供。
编辑:
我查看的 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 具有一组异构内核,请参阅 big.LITTLE。例如。骁龙 810 拥有 4 个 Cortex-A53 内核和 4 个 Cortex-A57 内核。当内核的调度程序认为合适时,您的线程将被调度并跨这些内核移动。在这种情况下,您在启动时获得的基准数据可能与代码最终安排在稍后的内核不匹配。
我正在针对 ARMv8 机器对库进行基准测试。我有四个 Cortex-A53 开发板,我们的 NEON 内在函数实现比 C/C++ 实现高出大约 30%。这是预期的。
GCC compile farm 提供了一个 Softiron Overdrive 1000。它是一个 Cortex-A57 服务器主板,C/C++ 代码比内部函数实现高出 50%。这真是令人惊讶。
我们想对 A-53 使用我们的 NEON 实现,但对 A57 使用 C/C++ 实现。我们有可以进行运行时特征选择的代码,例如 HasNEON()
、HasCRC()
、HasAES()
和 HasSHA()
。我们没有关于架构的任何信息,例如 A53 与 A57。
我的问题是,我们如何在运行时检测 A53 与 A57?
我们为 P4 处理器的 x86 代码路径提供了类似的代码。 P4 有一些慢字操作。我们通过检查 CPUID 位来检测 P4,但是 ARM 系统不同。 ARM系统类CPUID指令读取MSR,通常需要更高的权限级别(EL1或以上)。
如果有兴趣,Cortex-A57 对于特定的哈希算法来说速度较慢,因为它严重依赖于移位、旋转和异或运算。 A57 Optimization guide 告诉我们移位和旋转更昂贵。在 ASIMD 协处理器中需要 4 或 5 个周期进行移位,并且只有 F1 管道可以执行操作(根据第 3.14 节)。
也可能是 Cortex-A53 有同样的惩罚,它的整数单元更慢,所以非 NEON 代码没有优于 NEON 代码。
有一个在进程初始化期间调用的 tune()
函数,它对您的实现和 GCC 的实现进行基准测试并缓存结果(例如,在 bool isMyImplementationFaster
全局变量中)。
如果您的实现速度更快,您可以假设它是 A53(如果它更慢,您可以假设它是 A57)。请注意,对于既不是 A53 也不是 A57 的 CPU(包括未来的 CPU),这会导致 problem/confusion。然而;我希望你会意识到你实际上并不关心它是 A53 还是 A57(或其他东西),你只关心你的实现是 faster/slower.
一般来说,正如您和其他人所指出的,真正的 cpuid-like 指令在用户模式代码中不可用。实际上,相关信息以特定于平台的方式处理。
在 linux 上,您可以尝试解析 /proc/cpuinfo,如果 available/readable。 CPU implementer/architecture/variant/part 数字应该很好地识别不同的 CPU。此文件应在 Android.
上也可读 IIRC对于其他 OSes,OS 需要在某处提供必要的信息,但并非所有信息都可能提供。
编辑:
我查看的 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 具有一组异构内核,请参阅 big.LITTLE。例如。骁龙 810 拥有 4 个 Cortex-A53 内核和 4 个 Cortex-A57 内核。当内核的调度程序认为合适时,您的线程将被调度并跨这些内核移动。在这种情况下,您在启动时获得的基准数据可能与代码最终安排在稍后的内核不匹配。