如何将两个_pd转换为一个_ps
How to convert two _pd into one _ps?
我正在循环一些数据,计算一些双精度,每 2 个__m128d
操作,我想将数据存储在__m128
浮点数上。
所以 64+64 + 64+64(2 __m128d
(存储到 1 32+32+32+32 __m128
中。
我做这样的事情:
__m128d v_result;
__m128 v_result_float;
...
// some operations on v_result
// store the first two "slot" on float
v_result_float = _mm_cvtpd_ps(v_result);
// some operations on v_result
// I need to store the last two "slot" on float
v_result_float = _mm_cvtpd_ps(v_result); ?!?
但它每次都会覆盖(显然(前 2 个浮动"插槽"。
如何第二次"间隔"_mm_cvtpd_ps
以开始将值插入 3° 和 4° "槽"?
下面是完整的代码:
__m128d v_pA;
__m128d v_pB;
__m128d v_result;
__m128 v_result_float;
float *pCEnd = pTest + roundintup8(blockSize);
for (; pTest < pCEnd; pA += 8, pB += 8, pTest += 8) {
v_pA = _mm_load_pd(pA);
v_pB = _mm_load_pd(pB);
v_result = _mm_add_pd(v_pA, v_pB);
v_result = _mm_max_pd(v_boundLower, v_result);
v_result = _mm_min_pd(v_boundUpper, v_result);
v_result = _mm_mul_pd(v_rangeLn2per12, v_result);
v_result = _mm_add_pd(v_minLn2per12, v_result);
// two double processed: store in 1° and 2° float slot
v_result_float = _mm_cvtpd_ps(v_result);
v_pA = _mm_load_pd(pA + 2);
v_pB = _mm_load_pd(pB + 2);
v_result = _mm_add_pd(v_pA, v_pB);
v_result = _mm_max_pd(v_boundLower, v_result);
v_result = _mm_min_pd(v_boundUpper, v_result);
v_result = _mm_mul_pd(v_rangeLn2per12, v_result);
v_result = _mm_add_pd(v_minLn2per12, v_result);
// another two double processed: store in 3° and 4° float slot
v_result_float = _mm_cvtpd_ps(v_result); // fail
v_result_float = someFunction(v_result_float);
_mm_store_ps(pTest, v_result_float);
v_pA = _mm_load_pd(pA + 4);
v_pB = _mm_load_pd(pB + 4);
v_result = _mm_add_pd(v_pA, v_pB);
v_result = _mm_max_pd(v_boundLower, v_result);
v_result = _mm_min_pd(v_boundUpper, v_result);
v_result = _mm_mul_pd(v_rangeLn2per12, v_result);
v_result = _mm_add_pd(v_minLn2per12, v_result);
// two double processed: store in 1° and 2° float slot
v_result_float = _mm_cvtpd_ps(v_result);
v_pA = _mm_load_pd(pA + 6);
v_pB = _mm_load_pd(pB + 6);
v_result = _mm_add_pd(v_pA, v_pB);
v_result = _mm_max_pd(v_boundLower, v_result);
v_result = _mm_min_pd(v_boundUpper, v_result);
v_result = _mm_mul_pd(v_rangeLn2per12, v_result);
v_result = _mm_add_pd(v_minLn2per12, v_result);
// another two double processed: store in 3° and 4° float slot
v_result_float = _mm_cvtpd_ps(v_result); // fail
v_result_float = someFunction(v_result_float);
_mm_store_ps(pTest + 4, v_result_float);
}
您需要
使用 movlhps
( _mm_movelh_ps
将第二次转换的低词移动到第一次转换结果的高词。简化示例:
#include <immintrin.h>
__m128d some_double_operation(__m128d);
__m128 some_float_operation(__m128);
void foo(double const* input, float* output, int size)
{
// assuming everything is already nicely aligned ...
for(int i=0; i<size; i+=4, input+=4, output+=4)
{
__m128d res_lo = some_double_operation(_mm_load_pd(input));
__m128d res_hi = some_double_operation(_mm_load_pd(input+2));
__m128 res_float = _mm_movelh_ps(_mm_cvtpd_ps(res_lo), _mm_cvtpd_ps(res_hi));
__m128 res_final = some_float_operation(res_float);
_mm_store_ps(output, res_final);
}
}
神弩箭演示:https://godbolt.org/z/wgKjxN。
如果some_double_operation
是内联的,编译器可能会将第一个双精度操作的结果保存在第二次调用函数不使用的寄存器中,因此不需要将任何内容存储到内存中。
相关文章:
- 如何创建一个CMake变量,除非显式重写,否则使用默认值
- 删除一个线程上有数百万个字符串的大型哈希映射会影响另一个线程的性能
- 为什么两个不同的未命名名称空间可以共存于一个cpp文件中
- 运行同一解决方案的另一个项目的项目
- 挂起和取消挂起一个文件DLL
- 用C++中的一个变量定义一个常量
- 函数向量_指针有不同的原型,我可以构建一个吗
- 在c++中用vector填充一个简单的动态数组
- 如何在选项卡视图Qt中设置一个新项目,并保存以前的项目
- 预处理器:插入结构名称中的前一个行号
- 我在c++代码中生成了一个运行时#3异常
- 我想将一个对T类型的非常量左值引用绑定到一个T类型的临时值
- 从链接列表c++中删除一个项目
- 告诉一个 const char 数组,除了编译时 C 样式的字符串外,它不以 '