gcc - 如何使用 gcc 进行矢量化?

标签 gcc compiler-optimization simd auto-vectorization vector-processing

gcc的v4系列编译器可以使用 SIMD 自动向量化循环。某些现代 CPU 上的处理器,例如 AMD Athlon 或 Intel Pentium/Core 芯片。这是怎么做到的?

最佳答案

原始页面提供了有关让 gcc 自动矢量化的详细信息
循环,包括几个例子:

http://gcc.gnu.org/projects/tree-ssa/vectorization.html

虽然示例很棒,但事实证明,使用最新 GCC 调用这些选项的语法似乎发生了一些变化,请看现在:

  • https://gcc.gnu.org/onlinedocs/gcc/Developer-Options.html#index-fopt-info

  • 总之,以下选项适用于具有 SSE2 的 x86 芯片,
    给出已被矢量化的循环的日志:
    gcc -O2 -ftree-vectorize -msse2 -mfpmath=sse -ftree-vectorizer-verbose=5
    

    请注意,-msse 也是一种可能,但它只会向量化循环
    使用浮点数,而不是 double 数或整数。 (SSE2 是 x86-64 的基准。对于 32 位代码,也使用 -mfpmath=sse。这是 64 位的默认值,但不是 32 位的。)

    现代版本的 GCC 启用 -ftree-vectorize-O3所以只需在 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 时也默认关闭。

    关于gcc - 如何使用 gcc 进行矢量化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/409300/

    相关文章:

    linux - 链接期间未找到符号

    c++ - 数据结构的局部性是什么意思?

    c++ - 在 C++ 中捕获 lambda 的全局引用是否会抑制别名优化?

    c - 模拟 XMM 内在函数时在 WebAssembly 中进行对齐检查?

    c - 如何在 C 语言中使用 SSE 内在函数计算单 vector 点积

    c - OpenMP 卸载到 nvptx 时 gcc 7 和 8 (debian) 的问题

    针对 CPU 和内存使用的 GCC 优化

    ios - 为动态链接提供后备符号

    optimization - rustc/cargo 是否有 -march=native 等价物?

    x86 - 如何使用 avx2 将 24 位 rgb 转换为 32 位?