本文共 1754 字,大约阅读时间需要 5 分钟。
在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 来获取硬件featurestatic 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;}
转载地址:http://xjnmi.baihongyu.com/