SSE: 将__m128和__m128i转换为两个__m128d

3

两个相关的问题。

我的代码需要处理大量数据。它在内部循环中完成,性能非常重要。

  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);

输入和输出指针对齐,并且元素数量是4的倍数。主要问题是如何快速将__m128解包成两个__m128d。


为什么呢?我的意思是,我不明白预先计算整数和浮点数的双倍版本有什么优势。最终,FPU 加载双精度浮点数比加载浮点数或整数要慢,因为需要移动更多的数据。 - Skizz
为什么要在内部循环中进行转换?只需在线性时间内将所有数据转换为“double”,在嵌套循环中专门使用“double”(无需转换),然后再在线性时间内转换为结果类型。 - Ben Voigt
1个回答

7

这两个内置函数_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 );
    ....
}

_mm_cvtps_pd的链接已经失效,正确链接为http://msdn.microsoft.com/en-us/library/40x763ty.aspx。 - user9876
我认为在适当的转换后,即使是__m128,移位8位也可以正常工作。 - watson1180
_mm_srli_si128 操作是按字节而非位进行移位操作,而且它可以对所有寄存器类型进行移位。 - Christopher

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接