你很接近:
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);
}
诀窍是OR
两个比较结果,然后使用这个组合结果作为掩码,使用按位AND
运算将未通过测试的 X 值清零。然后添加掩码 X 向量,这将根据掩码将 0 或原始 X 值添加到 A 的每个元素。
对于您在下面的评论中提到的替代版本,您可以这样做:
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(P2f, cv); // <<< change this line to get a[i] += 2.0f
// instead of a[i] += x[i]
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);
}