繁体   English   中英

Visual C ++逗号运算符和sse内在函数

[英]Visual C++ comma operator and sse intrinsics

我一直在调试一些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。

使用Microsoft Visual Studio 2008、2010和2012构建此代码显示它们全部消除了逗号运算符的左操作数。 仅在启用优化的情况下才会发生这种情况。 使用gcc 4.8.1构建此代码时,即使使用了完全优化,也不会消除逗号运算符的左操作数。

C99规范指出:“逗号运算符的左操作数被评估为void表达式;评估后有一个序列点。然后评估右操作数”。

我认为,Microsoft优化器无法删除此代码。 这是因为语言规范指出两个操作数都被求值。 逗号运算符的两个操作数之间的唯一区别是它们的求值顺序,哪个为逗号运算符提供了结果。 在这种情况下,结果是无效的。

解决方法:用分号替换逗号。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM