【问题标题】:SSE: convert __m128 and __m128i into two __m128dSSE:将 __m128 和 __m128i 转换为两个 __m128d
【发布时间】:2011-05-24 18:28:07
【问题描述】:

两个相关的问题。

这是我的代码需要对相当大量的数据执行的操作。它是在内部循环中完成的,性能很重要。

  1. 将 __int32 和数组转换为双精度数(或将 __m128i 转换为两个 __m128d)。
  2. 将浮点数和数组转换为双精度数(或将 __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 加载双精度数据的速度将比浮点数或整数慢。
  • 为什么要在内部循环中进行转换?只需在线性时间内将所有数据预先转换为double,在嵌套循环内仅使用double(无需转换),然后再次在线性时间内转换为结果类型。

标签: c++ c optimization sse


【解决方案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 );
    ....
}

【讨论】:

  • _mm_cvtps_pd 的链接坏了,应该是msdn.microsoft.com/en-us/library/40x763ty.aspx
  • 我认为在正确转换后即使使用 __m128 移位 8 位也可以。
  • _mm_srli_si128 移动的是字节而不是位,是的,它移动了所有寄存器类型。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-05-30
  • 2015-08-03
  • 2012-11-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多