SSE: преобразовать __m128 и __m128i в два __m128d

Два связанных вопроса.

Это то, что мой код должен делать с довольно большим объемом данных. Это делается внутри внутренних циклов, и производительность важна.

  1. Преобразуйте массив __int32 в двойные (или преобразуйте __m128i в два __m128d).
  2. Преобразуйте и массив чисел с плавающей запятой в числа типа double (или конвертируйте __m128 в два __m128d).

В принципе, мне нужна функция со следующими подписями:

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

Указатели ввода и вывода выровнены, а количество элементов кратно 4. Основная проблема состоит в том, как быстро распаковать __m128 на два __m128d.


person watson1180    schedule 13.12.2010    source источник
comment
Почему именно? Я имею в виду, я не вижу, какое преимущество имеет предварительное вычисление двойной версии целых чисел и чисел с плавающей запятой. В конечном счете, FPU будет медленнее загружать двойники, чем числа с плавающей запятой или целые числа, поскольку перемещается больше данных.   -  person Skizz    schedule 13.12.2010
comment
Почему вы делаете преобразования внутри внутренних циклов? Просто преобразуйте все свои данные в double заранее за линейное время, используйте double исключительно внутри вложенных циклов (без необходимости преобразования) и затем конвертируйте в тип результата, снова за линейное время.   -  person Ben Voigt    schedule 13.12.2010


Ответы (1)


Внутренние функции _mm_cvtepi32_pd и _ mm_cvtps_pd преобразует значения в двойные.

Это должен быть цикл:

__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 );
    ....
}
person Christopher    schedule 13.12.2010
comment
Ссылка на _mm_cvtps_pd не работает, должна быть msdn.microsoft.com/en-us /library/40x763ty.aspx - person user9876; 13.12.2010
comment
Я предполагаю, что сдвиг на 8 бит будет работать даже с __m128 после правильного преобразования. - person watson1180; 14.12.2010
comment
_mm_srli_si128 сдвигает байты, а не биты, и да, сдвигает все типы регистров. - person Christopher; 14.12.2010