我们有一个(数字 3 浮点数)向量类,我希望将其对齐到 16 字节以允许 SIMD 操作。使用 declspec 进行 16 字节对齐会导致大量 C2719 错误(参数':带有 __declspec(align('#')) 的形式参数不会对齐)。如果我不能传递一个对齐的向量,那有什么意义呢?即使使用对向量的 const 引用也会导致编译器错误,这真的让我很恼火。
有没有办法在这里做我想做的事 - 获得 16 字节的类对齐,同时允许结构传递,而不必对 __m128 类型做一些愚蠢的把戏?
除非您一次对一堆这些 3 维向量结构进行操作,否则您不太可能从使用 SIMD 中获得太多好处,在这种情况下,您可能会将它们传递到一个数组中,您可以将其对齐为你需要。另一种可能从 SIMD 中获得好处的情况是,如果您对每个向量进行大量计算,并且可以并行化三个通道上的操作。在这种情况下,然后在函数的开头进行一些手动操作以将其转化为__m128
类型可能仍然会给您带来一些好处。
如果我不能传递一个对齐的向量,那有什么意义呢?
__declspec(align(#))
似乎相当无用。C++11 支持你想要的;alignas
似乎以所有__declspec(align(#))
被破坏的方式工作。例如,alignas
用于声明您的类型将导致该类型的参数对齐。
不幸的是,微软的编译器还不支持标准对齐说明符,而我所知道的唯一编译器是 Clang,它对 Windows 的支持有限。
无论如何,我只是想指出 C++ 有这个特性,它最终可能会提供给你。除非您可以移动到另一个平台,否则现在您最好不要按值传递参数,正如其他人提到的那样
当然,您不需要按值传递数组吗?而是传递一个指向 16 字节对齐数组的指针。还是我误解了什么?
Xbox360 支持 __declspec(passinreg),但目前 Visual Studio for Windows 不支持。
您可以在此处投票支持该功能的请求: http ://connect.microsoft.com/VisualStudio/feedback/details/381542/supporting-declspec-passinreg-in-windows
对于我们引擎中的向量参数,我们使用VectorParameter
typedef'edconst Vector
或const Vector&
取决于平台是否支持通过寄存器传递。
虽然这个问题很老,但 VC++ 编译器的情况并没有太大变化,所以也许这些笔记对某人有价值。1) 允许将带有 __declspec(align(X)) 的类或结构传递给函数的简单修复方法是通过引用传递。根据需要使用 const。2) 使用 SIMD 进行向量代数肯定是有原因的。通过将 quat multiply 和 quat rotate 函数切换为 SIMD,我能够将引擎中的动画和蒙皮传递速度提高 20%。没有对齐,没有数组。只有两个采用 float[4] 参数的函数。对于一开始写得不错并导致可衡量的 FPS 改进的东西,这没什么好打喷嚏的。而且由于这些是以后很难优化的东西,因此实际上不存在向量代数的过早优化之类的东西。3) 如果你把你的向量变成一个类,堆栈上所有多余的 _mm_store_ps 和 _mm_load_ps 指令都在 /O2 下优化。因此,虽然通过 SIMD 进行单个添加的收益可能可以忽略不计,但如果您有背靠背运行多个操作的情况,则生成的代码非常快。