2012-04-16 17 views
10

Czy istnieje sposób sprawdzenia, czy wszystkie bity/bajty/słowa itp. W zmiennej __m128i mają wartość 0?
W mojej aplikacji muszę sprawdzić, czy wszystkie liczby całkowite spakowane w zmiennej __m128i są zerami. Czy będę musiał je wyodrębnić i porównać osobno?

Edit: Sprawdź rejestr XMM dla wszystkich zer


Co robię teraz to:

int next = 0; 
do{ 
    //some code 

    next = idata.m128i_i32[0] + idata.m128i_i32[1] + idata.m128i_i32[2] + idata.m128i_i32[3]; 
}while(next > 0); 

Co potrzebne jest, aby sprawdzić, czy iData to wszystkie zera bez konieczności dostępu do każdego pojedynczego elementu, a wyjście z pętli, jeśli są one ...

podstawie komentarzu Harolda jest to rozwiązanie:


__m128i idata = _mm_setr_epi32(i,j,k,l); 
do{ 
    //some code 
}while(!_mm_testz_si128(idata, idata)); 

Spowoduje to wyjście z pętli, jeśli wszystkie małe bity każdego DW w idata wynoszą 0 ... dzięki hraold!

+0

Nie możesz użyć, powiedzmy, 'PCMPEQD' do porównania bez ekstrakcji? – dasblinkenlight

+0

Czy do rejestrów XMM jest dołączony rejestr flag? Jeśli tak, pomiędzy tymi bitami musi znajdować się flaga zero. –

+3

Zobacz "PTEST" jest dostępne w SSE4, w przeciwnym razie wymaga nieco więcej wysiłku. – harold

Odpowiedz

9

_mm_testz_si128 jest SSE4.1 która nie jest obsługiwana w niektórych procesorów (np Intel Atom, AMD Phenom)

Oto SSE2 kompatybilne wariant

inline bool isAllZeros(__m128i xmm) { 
    return _mm_movemask_epi8(_mm_cmpeq_epi8(xmm, _mm_setzero_si128())) == 0xFFFF; 
} 
4

jak Paul R skomentował na moim egzemplarzu post:

"Nie trzeba inicjować fałszywego argumentu dla drugiego parametru z PTEST, tj. zamiast _mm_testz_si128(idata, _mm_set1_epi32(0xFFFF)) można po prostu przetestować wartość przeciwko sobie."

ptest wykonuje całą pracę z jedną instrukcją.

Pomogło to.