如何将 4 个浮点数的 ps 向量转换为 4 个双精度数并存储到 pd 数组?

Posted

技术标签:

【中文标题】如何将 4 个浮点数的 ps 向量转换为 4 个双精度数并存储到 pd 数组?【英文标题】:How to convert a ps vector of 4 float to 4 doubles and store to a pd array? 【发布时间】:2019-02-04 14:53:52 【问题描述】:

SSE2/SIMD 是否可以将 __m128 值 (4 float) 存储到 double 的数组中?

我需要从此代码切换:

double *pC = c[voiceIndex];
__m128d v_result;

_mm_store_pd(pC, v_result);

到这里:

double *pC = c[voiceIndex];
__m128 v_result_float;

_mm_store_ps(pC, v_result_float);

除了对 4x 32 位 floats 进行 128 位存储,我需要将它们转换为 double

我无法更改“源”pC 数组(即double

【问题讨论】:

您想将 4 个浮点数转换为 4 个双精度数还是仅将 2 个浮点数存储到双精度数的每个位置? @chtz 将 4 个浮点数转换为 4 个双精度数,我相信(不确定您对第二种情况的含义)。因此,如果我将 0.1f、0.2f、0.3f 和 0.4f 存储到 v_result_float 中,我将分别将 0.1、0.2、0.3 和 0.4 存储到 pC[0]、pC[1]、pC[2] 和 pC[3] 【参考方案1】:

本质上,这是your previous question 的反问题。在这种情况下,您需要在转换后半部分之前将movhlps (_mm_movelh_ps) 高位字转换为低位字:

void foo(double* dest, __m128 input) 

    // assuming dest is nicely aligned
    _mm_store_pd(dest,   _mm_cvtps_pd(input));
    _mm_store_pd(dest+2, _mm_cvtps_pd(_mm_movehl_ps(input, input)));

【讨论】:

我明白了,谢谢!这似乎增加了一些开销(2 个存储而不是 1 个),而不是简单地“一次存储”。我会调查... 我没有看到另一种转换 __m128 寄存器的高位字的方法。在某些情况下,在double 域中执行所有操作可能是有意义的,而不是转换为float 并返回(假设这是float 向量的来源)。但这是您应该进行基准测试的事情(使用实际数据)。 我实际上需要这样做,因为我处理了一个近似函数 (exp),它使用浮点数准确且更快,而不是双精度数 使用 AVX 可以一次转换 4 个浮点数:_mm256_cvtps_pd 我只有 SSE2 ;)

以上是关于如何将 4 个浮点数的 ps 向量转换为 4 个双精度数并存储到 pd 数组?的主要内容,如果未能解决你的问题,请参考以下文章

_mm_storeu_ps 的 AVX 等效项?

你如何使用霓虹内在函数加载 3 个浮点数

如何将 map.getBounds() 作为 4 个浮点数的列表?

正确使用 _mm256_maskload_ps 将少于 8 个浮点数加载到 __m256

使用 SSE 将 4 个浮点数乘以 4 个浮点数的最有效方法是啥?

_mm_shuffle_ps() 等价于整数向量 (__m128i)?