2015-01-12 21 views
7

Tôi đang sử dụng SSE để xác định xem một hình chữ nhật (quy định bởi bốn int32 giá trị) đã thay đổi 0:Cách hiệu quả nhất để kiểm tra xem tất cả các thành phần __m128i là [sử dụng SSE intrinsics] intrinsics

__m128i oldRect; // contains old left, top, right, bottom packed to 128 bits 
__m128i newRect; // contains new left, top, right, bottom packed to 128 bits 

__m128i xor = _mm_xor_si128(oldRect, newRect); 

Tại thời điểm này, giá trị xor kết quả sẽ là tất cả các số không nếu hình chữ nhật không thay đổi. Vậy thì cách hiệu quả nhất để xác định điều đó là gì?

Hiện nay tôi đang làm như vậy:

if (xor.m128i_u64[0] | xor.m128i_u64[1]) 
{ 
    // rectangle changed 
} 

Nhưng tôi giả sử có một cách thông minh hơn (có thể sử dụng một số lệnh SSE mà tôi đã không tìm thấy chưa).

Tôi đang nhắm mục tiêu SSE4.1 trên x64 và tôi đang viết mã C++ trong Visual Studio 2013.

+1

Tại sao bạn đề cập đến giá trị số nguyên 128 bit dưới dạng 'NULL', là hằng số null * *? –

+0

@KeithThompson 'NULL' là macro mở rộng tới 0. C++ có' nullptr' là hằng số con trỏ null. – d7samurai

+1

'NULL' mở rộng đến một triển khai xác định hằng số con trỏ null C++. Nó * có thể * mở rộng thành 'nullptr'. Ngay cả khi nó xảy ra để mở rộng đến '0', nó không nên được sử dụng như một số nguyên. –

Trả lời

10

Bạn có thể sử dụng instuction PTEST qua _mm_testz_si128 nội tại (SSE4.1), như thế này:

#include "smmintrin.h" // SSE4.1 header 

if (!_mm_testz_si128(xor, xor)) 
{ 
    // rectangle has changed 
} 

Lưu ý rằng _mm_testz_si128 trả về 1 nếu bitwise AND của hai đối số bằng không.

5

Trớ trêu thay, ptest hướng dẫn từ SSE 4.1 có thể chậm hơn pmovmskb từ SSE2 trong một số trường hợp. Tôi đề nghị sử dụng đơn giản:

__m128i cmp = _mm_cmpeq_epi32(oldRect, newRect); 
if (_mm_movemask_epi8(cmp) != 0xFFFF) 
    //registers are different 

Lưu ý rằng nếu bạn thực sự cần giá trị xor, bạn sẽ phải tính toán riêng biệt.

Đối với bộ xử lý Intel Ivy Bridge như, phiên bản của PaulR với xor_mm_testz_si128 chuyển thành 4 UOPs, trong khi phiên bản đề nghị mà không tính toán xor chuyển thành 3 UOPs (xem thêm this thread). Điều này có thể dẫn đến thông lượng tốt hơn cho phiên bản của tôi.

+0

Chuỗi rất thú vị. Cảm ơn! –

+0

Độ trễ thêm này có còn là vấn đề trên Haswell không? Tôi đoán tôi nên viết một số mã điểm chuẩn và kiểm tra nó ... –

+0

@PaulR: Tôi không nhận được độ trễ mà bạn đang nói về. Tôi thường chỉ nhìn vào thông lượng, vì độ trễ là khó khăn hơn nhiều để phân tích và đo = ( Và ở đây "chậm" cũng có ý nghĩa về thông lượng, không phải độ trễ. Trong một số trường hợp, thông lượng của mã vectơ bị giới hạn bởi lối vào, chỉ có thể xử lý Vì vậy, trong những trường hợp này: nhiều uops = thông lượng chậm hơn – stgatilov

Các vấn đề liên quan