2010-12-13 4 views
3

두 가지 관련 질문.SSE : __m128 및 __m128i를 __m128d로 변환하십시오.

이것은 내 코드가 상당히 많은 양의 데이터로 처리해야하는 작업입니다. 내부 루프 내부에서 수행되므로 성능이 중요합니다.

  1. __int32를 double로 변환하거나 __m128i를 두 개의 __m128d로 변환합니다.
  2. float를 double로 변환하거나 __m128을 두 개의 __m128d로 변환합니다.

는 기본적으로, 나는 다음과 같은 서명과 기능이 필요합니다

void convert_int_to_double(__int32 const * input, double * output); 
void convert_float_to_double(float const * input, double * output); 

입력 및 출력 포인터가 정렬 및 요소의 수는 가장 큰 문제는 빨리로 __m128 압축을 해제하는 방법은 4의 배수 두 개의 __m128d.

+0

이유는, 정확히? 제 말은, int와 float의 이중 버전을 사전 계산하는 것이 어떤 이점이 있는지 알지 못합니다. 결과적으로 더 많은 데이터가 이동하기 때문에 궁극적으로 FPU는 float 또는 int보다 두 배 더 느리게로드됩니다. – Skizz

+0

내부 루프 내부에서 전환을 수행하는 이유는 무엇입니까? 모든 데이터를 선형 시간에 앞쪽에 'double'로 변환하고, 중첩 된 루프 내에서만 'double'을 사용하고 (변환이 필요 없음) 다시 선형 시간으로 결과 유형으로 변환하십시오. –

답변

6

내장 함수 _mm_cvtepi32_pd_mm_cvtps_pd은 값을 double로 변환합니다.

루프해야한다 :

__m128i* base_addr = ...; 
for(int i = 0; i < cnt; ++i) 
{ 
    __m128i epi32 = _mm_load_si128(base_addr + i); 
    __m128d v0 = _mm_cvtepi32_pd(epi32); 
    epi32 = _mm_srli_si128(epi32, 8); 
    __m128d v1 = _mm_cvtepi32_pd(epi32); 
    .... 
} 
+0

_mm_cvtps_pd에 대한 링크가 깨졌습니다. http://msdn.microsoft.com/en-us/library/40x763ty.aspx – user9876

+0

올바른 캐스팅을 한 후에도 8 비트 씩 이동하는 것이 __m128에서도 작동합니다. – watson1180

+0

_mm_srli_si128은 비트 단위가 아닌 바이트 단위로 시프트하며, 모든 레지스터 유형을 시프트합니다. – Christopher