在某种意义上,使用显式编译指示或依赖或使用自动矢量化来手动矢量化代码是否更好?为了使用自动矢量化获得最佳性能,必须监视编译器输出以确保循环被矢量化或修改它们直到它们是可矢量化的。

使用手动编码,可以确定正在发出所需的指令,但现在代码可能无法移植(无论是其他架构还是其他编译器)。

有帮助吗?

解决方案

自动矢量化对我来说永远不会很好。对我来说,似乎自动矢量化目前仅适用于非常微不足道的循环。

我使用pragma / intrinsic方法并查看程序集。如果编译器生成错误的代码(比如将SSE注册表溢出到堆栈或添加冗余移动),我会在整个循环体中使用内联汇编程序。

便携性不是问题。通常,您从C / C ++循环开始,并使用内在函数进行优化。只需保留旧循环并将其用作SIMD实现的单元测试/后备。此外,能够通过编译时定义从项目中删除所有SIMD代码总是明智的。以这种方式调试应用程序很多。相同的定义可用于交叉编译。

其他提示

我永远不会依赖任何编译器的自动矢量化。使用 gcc ,我会倍加警惕,因为 gcc 的优化效果总是因版本而异。几乎所有我认识的人都依赖于特殊的优化或gcc扩展,在发布新的 gcc 版本时必须处理破坏。

您通常可以信任编译指示和内在函数,但是您应该密切关注新gcc版本的发行说明,并且您应该告诉自己的用户编译代码需要哪些gcc版本。

当矢量化确实很重要时,我们已经在测试套件中添加了一些东西来调用 objdump 并验证实际上正在使用矢量指令。能够自动检测“坏矢量代码”(如Nils描述的那样)会很好,但我们从来没有这么做过。

我还没有看到一个比伤害更好的自动矢量化器。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top