내가 16 비트 데이터와 SSE 배열이 고려 된 데이터를 8 비트 등록 같은 첫 번째 8 바이트의 16 개 비트 데이터 :변환 8 16 비트 SSE는
{1,2,3,4,5,6,7,8,0,0,0,0,0,0,0,0}.
이 작업을 수행 할 수있는 SSE 명령어가 있는가?
내가 16 비트 데이터와 SSE 배열이 고려 된 데이터를 8 비트 등록 같은 첫 번째 8 바이트의 16 개 비트 데이터 :변환 8 16 비트 SSE는
{1,2,3,4,5,6,7,8,0,0,0,0,0,0,0,0}.
이 작업을 수행 할 수있는 SSE 명령어가 있는가?
위의 의견에서 @harold은 (는) pshufb
aka _mm_shuffle_epi8
으로 매우 쉽게 할 수 있습니다.
#include <stdio.h>
#include <tmmintrin.h>
static __m128i pack_16_to_8(const __m128i v)
{
const __m128i vperm = _mm_setr_epi8(0, 2, 4, 6, 8, 10, 12, 14, -1, -1, -1, -1, -1, -1, -1, -1);
return _mm_shuffle_epi8(v, vperm);
}
int main(void)
{
const __m128i v = _mm_setr_epi16(1, 2, 3, 4, 5, 6, 7, 8);
printf("%vhd -> %vd\n", v, pack_16_to_8(v));
return 0;
}
컴파일 및 실행
$ gcc -Wall -mssse3 pack_16_to_8.c && ./a.out
1 2 3 4 5 6 7 8 -> 1 2 3 4 5 6 7 8 0 0 0 0 0 0 0 0
추가 바울 К의 대답 :
SSE2 확장 명령 PACKSSWB(_mm_packs_epi16) 및 PACKUSWB (_mm_packus_epi16)이 포함되어 있습니다. 이 명령은 특별히 16 비트 벡터를 8 비트 벡터로 변환하도록 설계되었습니다. 이 값이 8 비트 부호없는 정수 (0..255) 범위를 초과하면 16 비트 (부호있는 및 부호없는) 값의 채도를 수행합니다.
#include <iostream>
#include <emmintrin.h>
template<class T> inline void Print(const __m128i & v)
{
T b[sizeof(v)/sizeof(T)];
_mm_storeu_si128((__m128i*)b, v);
for (int i = 0; i < sizeof(v)/sizeof(T); i++)
std::cout << int(b[i]) << " ";
std::cout << std::endl;
}
int main()
{
__m128i v16 = _mm_setr_epi16(1, 2, 3, 4, 5, 6, 7, 8);
Print<uint8_t>(_mm_packs_epi16(v16, _mm_setzero_si128()));
Print<uint8_t>(_mm_packus_epi16(v16, _mm_setzero_si128()));
return 0;
}
출력 :
1 2 3 4 5 6 7 8 0 0 0 0 0 0 0 0
1 2 3 4 5 6 7 8 0 0 0 0 0 0 0 0
이'pshufb' 실제 팩 지침 – harold
참조 포화되어, 그것을 할 수 https://stackoverflow.com/questions/46468026/fast-copy-every-second- 하나의 단일 벡터를 패킹하고 높은 64b에 0을 남기지 않고 배열을 통해이를 수행하기위한 바이트 - 대 - 새로운 - 메모리 - 영역. –