C中带有比较SSE的If语句

C中带有比较SSE的If语句,c,sse,C,Sse,我想做到这一点: for (int i=0;i<n,i++){ if (x[i] > 2.0f || x[i] < -2.0f) a[i] += x[i]; } for(int i=0;i 2.0f | | x[i]2?a+x:a+0 _mm_商店_ps(a+i,av); } 非常感谢。还有一件事,答案是如何改变的,不是a[i]+=x[i],而是a[i]+=2.0f?我也遇到了a[i]*=2.0f。将_-mm\u和_-ps替换为_-mm\u-mul\ps在这

我想做到这一点:

for (int i=0;i<n,i++){
  if (x[i] > 2.0f || x[i] < -2.0f) 
     a[i] += x[i]; 
}
for(int i=0;i 2.0f | | x[i]<-2.0f)
a[i]+=x[i];
}
我已经走了这么远,但不知道下一步该怎么办:

__m128 P2f = _mm_set1_ps(2.0f);
__m128 M2f = _mm_set1_ps(-2.0f);
for(int i=0;i<n,i+=4){
__m128 xv = _mm_load_ps(x+i);
__m128 av = _mm_load_ps(a+i);

__m128 c1 = _mm_cmpgt_ps(xv, P2f);
__m128 c2 = _mm_cmplt_ps(xv, M2f);

__m128 or = _mm_or_ps(c1,c2);
    =???==
av = _mm_add_ps(av, xv);
_mm_store_ps(a+i, av);
}
\uuuum128 P2f=\umm\uset1\ups(2.0f);
__m128 M2f=_mm_设置1_ps(-2.0f);
对于(int i=0;i你很接近:

const __m128 P2f = _mm_set1_ps(2.0f);
const __m128 M2f = _mm_set1_ps(-2.0f);
for (int i = 0; i < n; i += 4)
{
    __m128 xv = _mm_load_ps(x + i);
    __m128 av = _mm_load_ps(a + i);

    __m128 c1v = _mm_cmpgt_ps(xv, P2f);
    __m128 c2v = _mm_cmplt_ps(xv, M2f);

    __m128 cv = _mm_or_ps(c1v, c2v);

    xv = _mm_and_ps(xv, cv);

    av = _mm_add_ps(av, xv);

    _mm_store_ps(a + i, av);
}

对于您在后面的评论中提到的第三个版本(
a[i]*=2.0
),它稍微复杂一些,但是您可以将表达式看作
a[i]+=a[i]

const __m128 P2f = _mm_set1_ps(2.0f);
const __m128 M2f = _mm_set1_ps(-2.0f);
for (int i = 0; i < n; i += 4)
{
    __m128 xv = _mm_load_ps(x + i);
    __m128 av = _mm_load_ps(a + i);

    __m128 c1v = _mm_cmpgt_ps(xv, P2f);
    __m128 c2v = _mm_cmplt_ps(xv, M2f);

    __m128 cv = _mm_or_ps(c1v, c2v);

    xv = _mm_and_ps(av, cv)); // <<< change this line to get a[i] *= 2.0f (a[i] += a[i])
                              //     instead of a[i] += x[i]

    av = _mm_add_ps(av, xv);

    _mm_store_ps(a + i, av);
}
const\uuuum128 P2f=\umm\uset1\ups(2.0f);
常数m128 M2f=_mm_设置1_ps(-2.0f);
对于(int i=0;ixv=_-mm_和_-ps(av,cv));//我只想补充保罗的优秀答案,即你只需要利用关于零的对称性进行一次比较:

const __m128 absMask = (__m128)_mm_set1_epi32(0x7fffffff);
const __m128 two = _mm_set1_ps(2.0f);

for (int i = 0; i < n; i += 4) {
    __m128 xv = _mm_load_ps(x + i);
    __m128 av = _mm_load_ps(a + i);
    __m128 absxv = _mm_and_ps(xv, absMask); // |x|
    __m128 mask = _mm_cmpgt_ps(absxv, two); // |x| > 2 ?
    xv = _mm_and_ps(xv, cv);                // |x| > 2 ? x : 0
    av = _mm_add_ps(av, xv);                // |x| > 2 ? a + x : a + 0
    _mm_store_ps(a + i, av);
}
const\uuum128 absMask=(\uuuum128)\umm\uset1\uepi32(0x7fffff);
常数m128二=毫米设置1秒(2.0f);
对于(int i=0;i2?
xv=_-mm_和_-ps(xv,cv);/| x |>2?x:0
av=_mm_add_ps(av,xv);/|x |>2?a+x:a+0
_mm_商店_ps(a+i,av);
}

非常感谢。还有一件事,答案是如何改变的,不是a[i]+=x[i],而是a[i]+=2.0f?我也遇到了a[i]*=2.0f。将_-mm\u和_-ps替换为_-mm\u-mul\ps在这里似乎不起作用。除非我做错了什么。在这种情况下它也会起作用吗?@NeilDA:不-那不起作用,因为你需要将两者乘以1.0(无变化)或2.0(
*=2.0f
)。@NeilDA:我现在已经在上面的答案中添加了第三个案例。啊!我一直在努力解决这个问题,花了很多时间试图理解为什么+=起作用的地方它不起作用。希望我早一点知道这个诀窍。。谢谢:)
const __m128 absMask = (__m128)_mm_set1_epi32(0x7fffffff);
const __m128 two = _mm_set1_ps(2.0f);

for (int i = 0; i < n; i += 4) {
    __m128 xv = _mm_load_ps(x + i);
    __m128 av = _mm_load_ps(a + i);
    __m128 absxv = _mm_and_ps(xv, absMask); // |x|
    __m128 mask = _mm_cmpgt_ps(absxv, two); // |x| > 2 ?
    xv = _mm_and_ps(xv, cv);                // |x| > 2 ? x : 0
    av = _mm_add_ps(av, xv);                // |x| > 2 ? a + x : a + 0
    _mm_store_ps(a + i, av);
}