我正在编译没有AVX512支持,但我注意到immintrin. h为AVX512拖了大量的LOC,例如。
/usr/lib/gcc/x86_64-linux-gnu/11/include/avx512fintrin.h
我试过检查指定行军选项是否有帮助,但似乎没有帮助。
cat avx512_include.cpp
#include <immintrin.h>
int main() {}
g++ -march=core2 -E -P avx512_include.cpp | wc -l
34365
g++ -march=skylake-avx512 -E -P avx512_include.cpp | wc -l
34257
我知道,我可以在理论上破解我的gcc安装,并祈祷它会工作时,我删除所有的内容从avx512头😈,但我正在寻找一个支持的方式,如果有一个。
我试着查看gcc头文件的内部,看看是否有一些宏检查来包含avx512头文件,但它们似乎是无条件包含的。
我试图找到一个gcc三月标签,找不到任何,如果有人知道更合适的标签旁边的电流请评论
1条答案
按热度按时间6jjcrrmo1#
愚者/clang支持
__attribute__((target("avx512f")))
,以便在编译文件时使用AVX-512内容,而不使用-march=
,这意味着-mavx512f
。因此immintrin.h
仍必须拉入AVX 512定义。但是,如果您尝试在不启用
__m512i v = _mm512_set1_ps(1.0);
的情况下使用它,仍然会收到来自愚者的编译错误和clang。为了缩短编译时间,也许预编译头文件是一个选项。大多数Linux发行版默认情况下不这样做。
或者在根本不使用AVX-512的项目中,是的,你可以把东西砍下来,这样标头就不会被包括在内,或者至少不会被编译。
最不具侵入性的方法可能是在第一次包含文件之前定义愚者的include-guard宏。愚者的预处理器仍然会读取这些文件,但编译器本身不会在它们上面花费任何时间。从大小来看,avx 512 fintrin. h和avx 512 vlintrin. h是最大的宏; AMX和VNNI等都是小得多的头文件,所以可能只有
avx512*.h
才真正值得费心。也许把这个重定向到一个
skip-avx512.h
。但是,一些较新的文件定义了AVX-512版本的内部函数,因此,如果缺少
__mmask8
等的定义,则会破坏定义AVX-512内部函数 * 和 * 非AVX-512 VEX的gfniintrin.h
和vaesintrin.h
等标头您可以通过添加所涉及的键类型的定义来解决这个问题,或者也完全跳过那些报头。这在我的Arch Linux系统上的GCC12.2上可以使用。编译你的空测试用例而不进行优化:
启用优化后(Skylake上的
-O2 -march=native
),时间分别为295和79毫秒。如果
-O2
没有任何arch=,则为322 ms vs. 105 ms。也许不必运行#pragma target()
行是-march=
更快的原因。定义_GFNIINTRIN_H_INCLUDED
和其他两个将更快的时间降低到95 ms,因此显然这些相对较小的头文件产生了很大的差异。-O2
编译更多行可能会更慢,因为接受立即数的内部函数只是没有#ifdef __OPTIMIZE__
的宏。(即使函数在任何地方都没有内联,也可能会花费一些时间进行优化。)一个更激进的方法是创建一个
/usr/lib/gcc/x86_64-pc-linux-gnu/12.2.0/include/immintrin.h
的定制版本,并简单地删除avx512*
头文件的所有#include
行,以及其他一些太新而不想使用的行,如avxvnniintrin.h
、amx*
和shaintrin.h
。如果您不想完全跳过VAES、GFNI和VPCLMUL,则必须采取相同的预防措施。
或者把它命名为
"custom_gcc_intrin.h"
并包含它而不是immintrin.h
?或者把它命名为immintrin.h
,但把它放在特定项目中的某个地方,在那里它首先作为一个包含路径被查找?不要修改
immintrin.h
的系统副本,或者设置默认使用修改后的版本;这可能会在将来的某个时候咬你,当你试图编译的东西,确实有AVX-512代码路径与运行时检测。你会超级困惑为什么你的愚者是坏的,如果你忘记了这个修改多年前。