在ceph 的src/test/test_arch.cc 中我们可以看到下面的code ,从kernel中的/proc/cpuinfo 中的feature
来判断arm是否支持neon指令,需要注意这个指令在armv8 之后被称为asimd指令
TEST(Arch, all)
{
ceph_arch_probe();
EXPECT_TRUE(ceph_arch_probed);
#if (__arm__ || __aarch64__ || __x86_64__) && __linux__
char flags[FLAGS_SIZE];
FILE *f = popen("grep '^\\(flags\\|Features\\)[ ]*:' "
"/proc/cpuinfo | head -1", "r");
if(f == NULL || fgets(flags, FLAGS_SIZE - 1, f) == NULL) {
// silently do nothing if /proc/cpuinfo does exist, is not
// readable or does not contain the expected information
if (f)
pclose(f);
return;
}
pclose(f);
flags[strlen(flags) - 1] = ' ';
int expected;
#if (__arm__ || __aarch64__)
#从这里知道neon和asimd 是一回事
expected = (strstr(flags, " neon ") || strstr(flags, " asimd ")) ? 1 : 0;
EXPECT_EQ(expected, ceph_arch_neon);
#endif
除了通过/proc/cpuinfo 外更通用的方式是通过/proc/self/auxv 来获取硬件feature
static unsigned long get_auxval(unsigned long type)
{
unsigned long result = 0;
#打开这个文件
FILE *f = fopen("/proc/self/auxv", "r");
if (f) {
ElfW(auxv_t) entry;
#读取这个文件的AT_HWCAP
while (fread(&entry, sizeof(entry), 1, f) == 1) {
if (entry.a_type == type) {
result = entry.a_un.a_val;
break;
}
}
fclose(f);
}
return result;
}
static unsigned long get_hwcap(void)
{
return get_auxval(AT_HWCAP);
}
#endif // __linux__
int ceph_arch_arm_probe(void)
{
#从下面这段code 也可以知道arm下的neon 指令等同于arm64下的asimd指令
#if __arm__ && __linux__
ceph_arch_neon = (get_hwcap() & HWCAP_NEON) == HWCAP_NEON;
#elif __aarch64__ && __linux__
ceph_arch_neon = (get_hwcap() & HWCAP_ASIMD) == HWCAP_ASIMD;
# if defined(HAVE_ARMV8_CRC) && defined(HWCAP_CRC32)
ceph_arch_aarch64_crc32 = (get_hwcap() & HWCAP_CRC32) == HWCAP_CRC32;
# endif
#else
if (0)
get_hwcap(); // make compiler shut up
#endif
return 0;
}
arm 的neon指令等同于arm64的asimd指令
最新推荐文章于 2024-08-09 07:11:32 发布