我一直在调试一些 SSE 优化的矢量代码,并注意到一些奇怪的行为。公平地说,代码风格很糟糕,但编译器所做的对我来说仍然是错误的。这是有问题的功能:
inline void daxpy(int n, double alph, const double* x, int incx, double* y, int incy) {
__m128d sse_alph = _mm_load1_pd(&alph);
while (n >= 4) {
n -= 4;
__m128d y1 = _mm_load_pd(y+n), y2 = _mm_load_pd(y+n+2);
__m128d x1 = _mm_load_pd(x+n), x2 = _mm_load_pd(x+n+2);
y1 = _mm_add_pd(y1, _mm_mul_pd(x1, sse_alph));
y2 = _mm_add_pd(y2, _mm_mul_pd(x2, sse_alph));
_mm_store_pd(y+n, y1), _mm_store_pd(y+n+2, y2);
}
}
函数是数组y = y + alph * x。我们保证两个数组都具有相同的长度,n
即 4 的倍数,并且 x 和 y 在 16 字节边界上对齐(为了清楚起见,我省略了相关的断言)。
循环的最后一行是用逗号运算符编写的,因此它看起来像两条加载线。问题是第一次_mm_store_pd
调用没有被执行。那不是错了吗?我猜编译器可能已经决定只需要第二次调用来评估表达式,但内部函数似乎很明显有副作用。
我误解了这里发生了什么吗?我意识到使用像这样的逗号运算符是很糟糕的风格 - 我的问题是编译器是否错误。有问题的编译器是 Visual C++ 2010 SP 1。