【发布时间】:2010-09-29 09:39:24
【问题描述】:
在某种意义上,手动矢量化代码、使用显式 pragma 还是依赖或使用自动矢量化更好?为了使用自动矢量化获得最佳性能,必须监视编译器输出以确保循环被矢量化或修改它们直到它们可矢量化。
使用手动编码,可以确定正在发出所需的指令,但现在代码可能不可移植(对于其他架构或其他编译器)。
【问题讨论】:
标签: optimization gcc loops vector-processing
在某种意义上,手动矢量化代码、使用显式 pragma 还是依赖或使用自动矢量化更好?为了使用自动矢量化获得最佳性能,必须监视编译器输出以确保循环被矢量化或修改它们直到它们可矢量化。
使用手动编码,可以确定正在发出所需的指令,但现在代码可能不可移植(对于其他架构或其他编译器)。
【问题讨论】:
标签: optimization gcc loops vector-processing
自动矢量化对我来说从来都不是很好。在我看来,目前自动矢量化似乎只适用于非常琐碎的循环。
我使用 pragma/intrinsic 方法并查看程序集。如果编译器生成错误代码(例如将 SSE 寄存器溢出到堆栈上或添加多余的移动),我会为整个循环体使用内联汇编程序。
顺便说一句,便携性不是问题。通常,您从 C/C++ 循环开始并使用内在函数对其进行优化。只需保留旧循环并将其用作 SIMD 实现的单元测试/备用。此外,能够通过编译时定义从项目中删除所有 SIMD 代码总是明智的。以这种方式调试应用程序要容易得多。相同的定义可用于交叉编译。
【讨论】:
我永远不会依赖 any 编译器的自动矢量化。对于gcc,我会倍加小心,因为gcc 的优化效果总是因版本而异。当新的gcc 版本发布时,我认识的几乎所有依赖特殊优化或 gcc 扩展的人都必须处理损坏问题。
您通常可以信任 pragma 和内在函数,但您应该密切关注新 gcc 版本的发行说明,并且应该告诉您自己的用户编译您的代码需要哪个 gcc 版本。
有一次或两次,当向量化真的很重要时,我们在测试套件中添加了一些东西来调用objdump 并验证向量指令是否真正被使用。能够自动检测“坏矢量代码”(如 Nils 所描述的那样)也很好,但我们从未走到那一步。
【讨论】: