Bạn đang gần:
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);
}
Bí quyết là OR
hai kết quả so sánh và sau đó sử dụng kết quả này làm mặt nạ để loại trừ giá trị X không vượt qua bài kiểm tra bằng cách sử dụng thao tác bitwise AND
. Sau đó bạn thêm vectơ X có mặt nạ, sẽ thêm 0 hoặc giá trị X ban đầu cho mỗi phần tử của A theo mặt nạ.
Đối với phiên bản thay thế như đã đề cập trong nhận xét của bạn bên dưới, bạn muốn làm điều này:
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);
}
Đối với phiên bản thứ ba bạn đề cập đến trong ý kiến sau đây (a[i] *= 2.0
) nó hơi phức tạp hơn, nhưng bạn có thể làm điều đó bằng cách suy nghĩ về biểu thức dưới dạng 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);
}
Nguồn
2013-03-12 21:52:57
Cảm ơn rất nhiều. Một điều nữa, thay đổi câu trả lời thay vì [i] + = x [i], đó là [i] + = 2.0f? – NeilDA
Tôi cũng gặp phải một [i] * = 2.0f. Thay thế _mm_and_ps thành _mm_mul_ps dường như không hoạt động ở đây. Trừ khi tôi đang làm gì đó sai. Nó vẫn sẽ làm việc trong trường hợp đó? – NeilDA
@NeilDA: không - điều đó sẽ không hoạt động, vì bạn cần nhân với 1.0 (không thay đổi) hoặc 2.0 ('* = 2.0f'). –