我试图让矢量乘法矢量化,但它看起来像你做的任何事情,原因1200使它不受矢量化的影响:
循环包含阻止矢量化的循环携带数据依赖性。循环的不同迭代相互干扰,使得对循环进行矢量化会产生错误的答案,并且自动矢量化器无法证明自己没有这样的数据依赖性。
这是(例如)我希望被矢量化的运算符:
class cvec3 {
...
__forceinline void operator *=(const cvec3& v) {
x *= v.x;
y *= v.y;
z *= v.z;
}
...
}
我使用了以下测试代码:
inline void multiply_with(cvec3* __restrict arr1, const cvec3* __restrict arr2, int c)
{
// loop vectorized
for (int i = 0; i < c; i++) {
arr1[i].x *= arr2[i].x;
arr1[i].y *= arr2[i].y;
arr1[i].z *= arr2[i].z;
}
// loop vectorized
for (int i = 0; i < c; i++) {
MP_VEC_WITH(arr1[i], arr2[i]);
}
// loop not vectorized due to reason '1200'
for (int i = 0; i < c; i++) {
arr1[i] *= arr2[i];
}
}
是否可以让*=
运算符为类进行矢量化?可能有一些编译器提示我找不到?这不是我想要矢量化的唯一地方。在整个地方都有矢量数组上的循环并将它们全部写出来变得非常难以理解并且工作很多,看起来宏甚至会更好,这似乎也是一个坏主意。
还有一个小问题,你可以看到第二个循环确实用下面的宏进行了矢量化。这并不意味着什么,因为它导致完全相同的代码,但为什么编译器不能看到这与__forceinline重载运算符是一回事?
#define MP_VEC_WITH(a, b) { \
a.x *= b.x; \
a.y *= b.y; \
a.z *= b.z; \
}
理想情况下,我希望像这样的东西被矢量化(如果我将循环写入3次,每次向量组件写入一次,它会进行矢量化。)
for (uint32_t i = 0; i < pCount; i++) {
vec3 tranformation = (in_velocities[i] + in_forces[i] * dt * in_invMasses[i]) * dt;
out_pos_change[i] = tranformation;
out_position[i] = in_positions[i] + tranformation;
}
编辑: 我正在使用Microsoft C / C ++编译器(在Visual Studio 2015中)。