移动 __m128 的上下浮点数
move lower and upper floats of __m128
如何将 __m128
的上下浮点数移动成两个 __m128
并清零另一半。
由于您没有指定,我假设意图是使用 SSE 内在函数。我还假设至少 SSE2 可用,因为这基本上是最近 x86-64 设置的基线……
一种非常直白的方式来做你上面描述的是简单地复制输入的低 64 位并通过 _mm_move_epi64()
将高 64 位归零
__m128 lo2(__m128 x)
{
return _mm_castsi128_ps(_mm_move_epi64(_mm_castps_si128(x)));
}
并使用_mm_move_sd()
复制输入的高64位和从零开始复制低64位
__m128 hi2(__m128 x)
{
return _mm_castpd_ps(_mm_move_sd(_mm_castps_pd(x), _mm_setzero_pd()));
}
工作示例here
_mm_movelh_ps()
和 _mm_movehl_ps()
与全零寄存器相结合,可以满足您的需求吗?
#include <iostream>
#include <x86intrin.h>
void print_vec(__m128 a) {
alignas(16) float res[4];
_mm_store_ps(res, a);
std::cout << res[0] << '\t' << res[1] << '\t' << res[2] << '\t' << res[3]
<< '\n';
}
int main() {
__m128 vec = _mm_set_ps(4.0f, 3.0f, 2.0f, 1.0f);
__m128 lo = _mm_movelh_ps(vec, _mm_setzero_ps());
__m128 hi = _mm_movehl_ps(vec, _mm_setzero_ps());
std::cout << "Orig:\t";
print_vec(vec);
std::cout << "Lower:\t";
print_vec(lo);
std::cout << "Upper:\t";
print_vec(hi);
return 0;
}
编译和 运行 这会产生:
Orig: 1 2 3 4
Lower: 1 2 0 0
Upper: 0 0 3 4
如何将 __m128
的上下浮点数移动成两个 __m128
并清零另一半。
由于您没有指定,我假设意图是使用 SSE 内在函数。我还假设至少 SSE2 可用,因为这基本上是最近 x86-64 设置的基线……
一种非常直白的方式来做你上面描述的是简单地复制输入的低 64 位并通过 _mm_move_epi64()
__m128 lo2(__m128 x)
{
return _mm_castsi128_ps(_mm_move_epi64(_mm_castps_si128(x)));
}
并使用_mm_move_sd()
复制输入的高64位和从零开始复制低64位
__m128 hi2(__m128 x)
{
return _mm_castpd_ps(_mm_move_sd(_mm_castps_pd(x), _mm_setzero_pd()));
}
工作示例here
_mm_movelh_ps()
和 _mm_movehl_ps()
与全零寄存器相结合,可以满足您的需求吗?
#include <iostream>
#include <x86intrin.h>
void print_vec(__m128 a) {
alignas(16) float res[4];
_mm_store_ps(res, a);
std::cout << res[0] << '\t' << res[1] << '\t' << res[2] << '\t' << res[3]
<< '\n';
}
int main() {
__m128 vec = _mm_set_ps(4.0f, 3.0f, 2.0f, 1.0f);
__m128 lo = _mm_movelh_ps(vec, _mm_setzero_ps());
__m128 hi = _mm_movehl_ps(vec, _mm_setzero_ps());
std::cout << "Orig:\t";
print_vec(vec);
std::cout << "Lower:\t";
print_vec(lo);
std::cout << "Upper:\t";
print_vec(hi);
return 0;
}
编译和 运行 这会产生:
Orig: 1 2 3 4
Lower: 1 2 0 0
Upper: 0 0 3 4