Es gibt keine Byte-Element-Verschiebung (psrlb
oder was auch immer), so dass Sie nicht nur die Bits abschlagen können Sie mit Recht nicht wollen, und dann Verschiebung nach links. Auch wenn Sie dies nur einmal tun müssen, ist es möglicherweise immer noch am besten, eine Maske zu verwenden.
Sie können generate the mask on the fly in fewer instruction bytes than it takes to store the mask, ohne die Möglichkeit eines Cache-Miss.
pcmpeqw xmm1,xmm1 ; -1
pabsb xmm1,xmm1 ; 1
psllw xmm1, 7 ; set1_epi8(0x80)
pand xmm1, xmm0
Wenn Sie die Vorzeichenbits zusammengepackt in einer ganzen Zahl reg wollen
PMOVMSKB reg, xmm0
Aber Auspacken das zurück auf einen Vektor langsamer ist als die Erzeugung der Vorzeichenbit-Maske (until AVX512).
Wenn Sie dies nur einmal tun, Sie könnte der Lage sein, mit etwas einfallen lassen, die kürzer als 4 insns, esp. wenn Sie AVX zerstörungsfreie Operationen verwenden können. Hier ist eine Idee, die nicht kürzer am Ende hat:
vpcmpeqw xmm1, xmm1,xmm1
vpsignb xmm2, xmm1, xmm0 ; xmm2 = -1 or +1 (or 0) depending on xmm0
vpsubb xmm3, xmm2, xmm1 ; xmm3 = 0 or +2 (or +1) depending on xmm0. (subtract -1 => add 1)
vpsllw xmm4, xmm3, 6 ; xmm4 = 0 or 0x80 (or 0x40) depending on xmm0
Nö, war nicht kürzer. Je nachdem, was Sie brauchen, könnte ein Teil dieser Idee helfen.
Haben Sie '_mm_and_si128()' ausprobiert? – Mysticial
Ich kann mir vorstellen '_mm_and_si128' zu verwenden (d. H.' Pand'), aber das erfordert, dass ich zuerst eine passende Maske lade. (Was ist der effizienteste Weg, dies zu tun?) Ich frage mich, ob es etwas Spezialisiertes gibt, das es besser machen kann. – jacobsa