2016-02-25 5 views
2

_mm_cvtepi16_epi32 (pmovsxwd) требует SSE4.1заменить _mm_cvtepi16_epi32 используя только SSE3

Как мы можем подписаться расширить векторные элементы только с SSE3, или SSE2?

Ответ на вопрос SSSE3 может быть интересным.

+2

Возможный дубликат размера ["Расширить" тип данных в регистре SSE] (http://stackoverflow.com/questions/14724419/extend-data-type-size-in-sse-register). Я не мог найти этот дубликат, пока не выработал ответ, поэтому я мог бы сделать google на _mm_unpacklo_epi16 _mm_srai_epi32. Это не вызвало «_mm_cvtepi16_epi32 без sse4.1», так что это не плохой вопрос. Это дубликат, но не тот, который я ожидал бы от OP самостоятельно. –

ответ

2

Дублируйте каждый 16-разрядный элемент (с нижней половины) с помощью распаковки, затем используйте арифметический сдвиг вправо, чтобы оставить копию знакового бита в верхней половине каждого элемента 32b.

__m128i v16 = ...; 
v32 = _mm_unpacklo_epi16(v16, v16); // [ a a b b c c d d ] 
v32 = _mm_srai_epi32(v32, 16); 

Это только SSE2. Это две быстрые инструкции, поэтому я не думаю, что есть что-то, что можно получить от SSE3 или SSSE3, и ничего не может придумать. Единственное, что было бы лучше, чем это, было бы способом сделать это неразрушающим образом (поэтому компилятору не нужно копировать v16, если он нам по-прежнему нужен).

Если вы уже могли это сделать в одной инструкции, pmovsxwd, возможно, не были представлены. (Хотя это может быть в любом случае согласовано с другими формами pmovsx. Где pmovsx действительно светит при переходе от байта в dword или байт к qword. Кроме того, форма загрузки является приятной, даже несмотря на то, что intrinsics очень трудно использовать как нагрузка.)

Для других размеров элементов существует psraw, поэтому 8-> 16 также эффективен, но нет psraq (только логические сдвиги влево/вправо для 64-битных элементов). pmovsxdq сложнее подражать. pblendw также SSE4.1. Я думаю, может быть, распаковать с нулями, а затем с арифметическим правым сдвигом. Затем вы можете OR с вектором, который распакован с нулями другим способом.

Это то, что вы можете использовать _mm_unpackhi, чтобы получить верхнюю половину, что pmovsz/pmovzx, к сожалению, не нужно.