原始页面提供了有关让 gcc 自动矢量化的详细信息
循环,包括几个例子:
http://gcc.gnu.org/projects/tree-ssa/vectorization.html
虽然示例很棒,但使用最新的 GCC 调用这些选项的语法似乎发生了一些变化,请看:
总之,以下选项适用于带有 SSE2 的 x86 芯片,
给出已被矢量化的循环的日志:
gcc -O2 -ftree-vectorize -msse2 -mfpmath=sse -ftree-vectorizer-verbose=5
请注意,-msse 也是一种可能,但它只会向量化循环
使用浮点数,而不是双精度数或整数。 (SSE2 是 x86-64 的基线。对于 32 位代码,也使用 -mfpmath=sse。这是 64 位的默认值,但不是 32 位。)
现代版本的 GCC 在 -O3 启用 -ftree-vectorize,所以只需在 GCC4.x 及更高版本中使用它:
gcc -O3 -msse2 -mfpmath=sse -ftree-vectorizer-verbose=5
(Clang 在-O2 启用自动矢量化。ICC 默认启用优化 + 快速数学。)
以下大部分内容由 Peter Cordes 撰写,他本可以写一个新答案。随着时间的推移,随着编译器的变化,选项和编译器输出也会发生变化。我不完全确定是否值得在这里详细跟踪它。注释? -- 作者
要同时使用您正在编译的硬件支持的指令集扩展并进行调整,请使用-march=native。
归约循环(如数组的总和)将需要 OpenMP 或 -ffast-math 将 FP 数学视为关联和矢量化。 Example on the Godbolt compiler explorer with -O3 -march=native -ffast-math 包括一个没有-ffast-math 的标量减少(数组总和)。 (好吧,GCC8 及更高版本进行 SIMD 加载,然后将其解压缩为标量元素,这与简单展开相比毫无意义。addss 依赖链的延迟循环瓶颈。)
有时您不需要-ffast-math,只需-fno-math-errno 可以帮助gcc 内联数学函数并将涉及sqrt 和/或rint / nearbyint 的内容向量化。
其他有用的选项包括-flto(跨文件内联、常量传播等的链接时间优化)和/或使用-fprofile-generate的配置文件引导优化/具有实际输入的测试运行/ -fprofile-use。 PGO 为“热”循环启用循环展开;在现代 GCC 中,即使在 -O3 时也默认关闭。