我正在构建一个安装程序/下载程序,它检测体系结构并下载用该体系结构编译的主要可执行文件的版本。如果它还不存在,它将在服务器上动态编译。
我可以很容易地获得CPU名称,例如"Intel(R) Core(TM) i9-10900KF CPU @ 3.70 ghz",但是我如何将其转换为MinGW的-march和-mtune设置的正确字符串?
我不能依赖于任何依赖关系,它需要能够确定这使用一个独立的脚本或可执行文件,可以由安装程序运行,以确定正确的字符串。或者我可以使用所有CPU名称的大列表转换为-march字符串,但我在哪里找到它?
编辑:我不能使用-march=native,因为编译器不在客户机上。我所做的是通过安装程序检测客户机上的体系结构,然后在服务器上编译它们的体系结构。所以我不能使用-march=native.
如果您可以分发MinGW的gcc.exe
编译器驱动程序(只是那个小文件和它所依赖的库,没有兆字节的语言前端cc1.exe
,cc1plus.exe
等),那么您可以在客户端机器上运行-###
选项,如下所示:
gcc.exe -### -xc - -E -march=native
,并从输出的cc1.exe
行中获取各种-m
和--param
选项。
-march=native
的工作原理,请查看driver-i386。cc和common/config/i386的GCC源代码。如果您从那里复制,我建议将结果作为一个独立的工具,您可以根据GPL发布,尊重这些文件的原始许可。
可以使用cpuid指令查询CPU的特性信息。以下是带有相应标志的大多数特性。
std::vector<std::string> get_cpu_flags() {
std::vector<std::string> flags;
int info[4];
__cpuid(info, 1);
std::bitset<32> edx_features(info[3]);
std::bitset<32> ecx_features(info[2]);
if (edx_features[23]) flags.push_back("mmx");
if (edx_features[25]) flags.push_back("sse");
if (edx_features[26]) flags.push_back("sse2");
if (ecx_features[0]) flags.push_back("sse3");
if (ecx_features[9]) flags.push_back("ssse3");
if (ecx_features[19]) flags.push_back("sse4_1");
if (ecx_features[20]) flags.push_back("sse4_2");
if (ecx_features[28]) flags.push_back("avx");
if (ecx_features[12]) flags.push_back("fma");
__cpuid(info, 7);
std::bitset<32> ebx_features(info[1]);
std::bitset<32> ecx_features_level7(info[2]);
if (ebx_features[5]) flags.push_back("avx2");
if (ebx_features[16]) flags.push_back("avx512f");
if (ebx_features[17]) flags.push_back("avx512dq");
if (ebx_features[21]) flags.push_back("avx512ifma");
if (ebx_features[26]) flags.push_back("avx512pf");
if (ebx_features[27]) flags.push_back("avx512er");
if (ebx_features[28]) flags.push_back("avx512cd");
if (ebx_features[30]) flags.push_back("avx512bw");
if (ebx_features[31]) flags.push_back("avx512vl");
if (ecx_features_level7[1]) flags.push_back("avx512vbmi");
if (ecx_features_level7[14]) flags.push_back("avx512vbmi2");
if (ecx_features_level7[30]) flags.push_back("avx512_vnni");
return flags;
}