2011-11-03 24 views
11

__m128i değişkeninin SSE-2 ve önceki işlemcilerde sıfır olmayan bir değere sahip olup olmadığını nasıl test ederim?__m128i değişken sıfır mıdır?

+0

Sıfır olmayan bit mi, yoksa 8/16/32 bit tam sayı mı? –

+0

@BrettHale: Sıfır olup olmadığını test ediyorum. – Mehrdad

cevap

11

SSE2 size yapabilirsiniz: Sıfır sonra, yani int gelen her sizin bit uzaklıklar 0'dan olurdu her byte için 4 bir maske dönmek vs

__m128i zero = _mm_setzero_si128(); 
if(_mm_movemask_epi8(_mm_cmpeq_epi32(x,zero)) == 0xFFFF) 
{ 
    //the code... 
} 

bu dört int 's test edecek, 8 & 12, ancak herhangi bir bit ayarlanırsa yukarıdaki test yakalayacaktır, eğer maskeyi koruyorsanız, ihtiyacınız olduğunda daha ince taneli kısımlarla doğrudan çalışabilirsiniz.

+2

+1, benimkinden daha iyi. :) Movemask komutunu hiç kullanmadım, böylece bunu yapabileceğinizi bilmiyordum. XD – Mysticial

+0

+1 En kompakt çözüm gördüm, teşekkürler! – Mehrdad

+3

Aksi halde mükemmel cevapta bir hata var - eğer tüm sıfırları kontrol ediyorsanız, eğer (_mm_movemask_epi8 (_mm_cmpeq_epi32 (x, sıfır)) == 0xFFFF) 'olmalıdır. Bunun nedeni, _mm_cmpeq_epi32'nin int'yi 0'a eşit değil, tüm 0'lara değil, sıfıra eşitse ve sonra '_mm_movemask_epi8' argümandaki her bir byte'ın en anlamlı bitini temel alan ilk 16 biti ayarlamasıdır. Umarım yazar cevabı düzenleyebilir - Ben denedim ama reddedildi. – FarmerBob

1

Bütünlük adına, SSE4 ile _mm_testz_si128'u kullanabilirsiniz. tüm bitleri sıfır olduğunda bu gerçek olduğunu

const bool isAllZero = _mm_testz_si128(a,a); 

Not.

+1

Bu aslında biraz daha hızlıdır ve test etmek için tamamen sıfır kayıt gerektirmez. 'ptest' /' jz' 2 + 1 uop'dur (makro-sigorta içermez). pcmpeq (1uop)/'pmovmsk' (1uop) /' ve 0xffff' (1uop)/'cmp 0xffff/je' (1uop). Eğer diğer durumu test ediyorsanız (* tüm * sıfır elemanlar yerine * * sıfır elemanlar), şu anki Intel ve AMD işlemcilerde yaklaşık olarak aynı performansa sahip olacaklardır: “ptest”/“jnz” (3 uops) vs . pcmpeq/pmovmsk/test/jnz (3 uops). –

+0

@PeterCordes Peki, bu durumda, hepsinde bir kayıt seti ve '_mm_testc_si128' kullanarak? Const bool atLeastOneZero = _mm_testc_si128 (a, allOnes) ' – Antonio

+1

gibi bir şey tekrar,' ptest' biraz daha hızlıdır. Bunu ptest olmadan yapmak için, all-one'lara karşı pcmpeq 'olacaksınız ve tüm elemanların eşleştiğini kontrol etmek için tam olarak aynı sırayla ilerleyeceksiniz. Pcmpeq ile all-zero ya da all-one için kontrol etmek, sabitlerin sinekte daha kolay üretilmesi (= pxor aynı, aynı ya da aynı pcmpeqw = same'). –