이 질문은 이전에 답변 된 질문입니다. Fast 24-bit array -> 32-bit array conversion? 하나의 대답으로, interjay 친절하게도 RGB24 -> RGB32 변환을위한 SSE3 코드를 게시했지만, 나는 또한 역방향 변환 (RGB32 -> RGB24) . 나는 그것을 쏜 (아래 참조)과 내 코드는 확실히 작동하지만, 그것은 interjay의 코드보다 복잡하고, 눈에 띄게 느린 너무했습니다. 지침을 정확히 역전하는 방법을 알 수 없었습니다. _mm_alignr_epi8은이 경우 도움이되지 않지만 SSE3에 익숙하지 않았습니다. 비대칭 성은 피할 수 없습니까, 아니면 교대조와 ORing을 대신 할 수 있습니까?고속 32 비트 어레이 -> SSE3에서 24 비트 어레이 변환? (RGB32 -> RGB24)
RGB32 -> RGB24 :
__m128i *src = ...
__m128i *dst = ...
__m128i mask = _mm_setr_epi8(0,1,2,4, 5,6,8,9, 10,12,13,14, -1,-1,-1,-1);
for (UINT i = 0; i < Pixels; i += 16) {
__m128i sa = _mm_shuffle_epi8(_mm_load_si128(src), mask);
__m128i sb = _mm_shuffle_epi8(_mm_load_si128(src + 1), mask);
__m128i sc = _mm_shuffle_epi8(_mm_load_si128(src + 2), mask);
__m128i sd = _mm_shuffle_epi8(_mm_load_si128(src + 3), mask);
_mm_store_si128(dst, _mm_or_si128(sa, _mm_slli_si128(sb, 12)));
_mm_store_si128(dst + 1, _mm_or_si128(_mm_srli_si128(sb, 4), _mm_slli_si128(sc, 8)));
_mm_store_si128(dst + 2, _mm_or_si128(_mm_srli_si128(sc, 8), _mm_slli_si128(sd, 4)));
src += 4;
dst += 3;
}
RGB24 -> RGB32 (의례 interjay는) :
__m128i *src = ...
__m128i *dst = ...
__m128i mask = _mm_setr_epi8(0,1,2,-1, 3,4,5,-1, 6,7,8,-1, 9,10,11,-1);
for (UINT i = 0; i < Pixels; i += 16) {
__m128i sa = _mm_load_si128(src);
__m128i sb = _mm_load_si128(src + 1);
__m128i sc = _mm_load_si128(src + 2);
__m128i val = _mm_shuffle_epi8(sa, mask);
_mm_store_si128(dst, val);
val = _mm_shuffle_epi8(_mm_alignr_epi8(sb, sa, 12), mask);
_mm_store_si128(dst + 1, val);
val = _mm_shuffle_epi8(_mm_alignr_epi8(sc, sb, 8), mask);
_mm_store_si128(dst + 2, val);
val = _mm_shuffle_epi8(_mm_alignr_epi8(sc, sc, 4), mask);
_mm_store_si128(dst + 3, val);
src += 3;
dst += 4;
}
그래서 SSE4.1은 허용되지 않습니까? – harold
4 개의 입력 레지스터에서 6 개의 마스크를 사용하여 3 개의 출력 레지스터로 변환하면됩니다. 'pshufb'는 1 바이트를 0으로 설정하거나 마스크로 색인 된 값으로 설정하기 때문에 3 개 또는 3 개를 사용할 수 없습니다. – hirschhornsalz