2016-12-19 7 views
3

기본적으로 AVX2 내장 함수로 이와 동등한 것을 작성하려면 어떻게해야합니까? 여기서 result_in_float__m256이고 은 short int* 또는 short int[8]입니다.avx 명령어를 사용하여 float 벡터를 짧은 int로 변환하려면 어떻게해야합니까?

for(i = 0; i < 8; i++) 
    result[i] = (short int)result_in_float[i]; 

나는 수레가 __m256i _mm256_cvtps_epi32(__m256 m1)이 고유 사용하여 32 개 비트 정수로 변환 할 수 있다는 것을 알고 있지만, 어떻게 더 16 개 비트 정수로 이러한 32 개 비트 정수를 변환하는 아무 생각이 없습니다. 그리고 나는 그 값을 (16 비트 정수 형태로) 메모리에 저장하는 것을 원하지 않으며 벡터 명령을 사용하여 그 값을 모두 수행하려고합니다.

인터넷 검색을 통해 _mm256_mask_storeu_epi16이라는 이름의 내장이 발견되었지만 그 사용법에 대한 예를 찾을 수 없어서 트릭을 수행 할 수 있는지 확실하지 않습니다.

+0

내가 모두 C와 C를 사용 ++. 그리고 이러한 내장 함수는 둘 중 하나에서 호출 할 수 있습니다. 그래서, 그것이 바로 그 이유입니다. – pythonic

+0

적절한 바이트 선택으로 vpshufb를 사용한 다음 상위 128 비트 레인에서 하위로 값을 가져 오는 임의의 셔플을 사용합니다. –

+0

오버 플로우를 감싸는 대신에 포화 시키면 괜찮습니까? (int에서 short로, 즉 float에서 int step으로)? – harold

답변

4

_mm256_cvtps_epi32은 좋은 첫 걸음입니다. 단편 포장 된 벡터로의 변환은 다소 짜증이 나며 크로스 슬라이스 셔플이 필요합니다 (여기서는 종속성 체인에 포함되지 않았 음). 값이 (주석에 따라), 우리는 변환을 수행하는 대신 _mm256_shuffle_epi8_mm256_packs_epi32를 사용할 수있는 권리 범위에있는 것으로 간주 될 수 있기 때문에

, 어느 쪽이든 그것은 포트 5에 1 사이클 명령입니다하지만 _mm256_packs_epi32을 피를 사용하여 어딘가에서 뒤섞인 마스크를 가져와야합니다.

그래서 그것은 단지 유형을 변경

__m256i tmp = _mm256_cvtps_epi32(result_in_float); 
tmp = _mm256_packs_epi32(tmp, _mm256_setzero_si256()); 
tmp = _mm256_permute4x64_epi64(tmp, 0xD8); 
__m128i res = _mm256_castsi256_si128(tmp); 
// _mm_store_si128 that 

마지막 단계 (캐스팅) 무료입니다 (테스트하지) 그것을 함께 넣어.

는 변환 수레의 두 벡터가 있다면, 당신은 다시 사용할 수있는 지침의 대부분을, 예를 들면 : (안 중 하나를 테스트)

__m256i tmp1 = _mm256_cvtps_epi32(result_in_float1); 
__m256i tmp2 = _mm256_cvtps_epi32(result_in_float2); 
tmp1 = _mm256_packs_epi32(tmp1, tmp2); 
tmp1 = _mm256_permute4x64_epi64(tmp1, 0xD8); 
// _mm256_store_si256 this 
+0

당신은 선생님입니다. 나는 당신의 코드를 테스트했고 효과가 있었다! 하나의 정정. __mm256i 또는 __mm128i 대신 _m256i 및 _m128i 여야합니다. 내가 사용한 정확한 코드는 다음과 같습니다. __m256i tmp = _mm256_cvtps_epi32 (result_in_float); \t tmp = _mm256_packs_epi32 (tmp, _mm256_setzero_si256()); \t tmp = _mm256_permute4x64_epi64 (tmp, 0xD8); – pythonic

+0

오른쪽, 싱글'm'이 있는데, 바꿀 께 – harold

+3

@pythonic and harold : 단일 벡터의 경우, 임시 (AVX1 만 필요함) :'_mm256_cvtps_epi32','_mm256_extractf128_si256' 그리고 128 비트'_mm_packs_epi32'에 대한 입력으로 캐스팅되었습니다. (나는 256b [VCVTPS2DQ ymm] (http://www.felixcloutier.com/x86/CVTPS2DQ.html)이 AVX1에 있다고 확신하지 못했다. –