假设我有四个__m128i
变量,其中包含一些计算产生的数据。例如,让我们说:
__m128i a = _mm_set_epi64x(1, 11);
__m128i b = _mm_set_epi64x(2, 22);
__m128i c = _mm_set_epi64x(3, 33);
__m128i d = _mm_set_epi64x(4, 44);
我想初始化两个__m256i
变量,其中第一个变量包含四个变量的所有高64位,第二个变量包含每个变量的低64位。所以我希望:
__m256i x = ...; // x = { 4, 3, 2, 1 };
__m256i y = ...; // y = { 44, 33, 22, 11 };
这样做的显而易见的方法是使用_mm256_set_epi64x
和_mm_extract_epi64
。但是,它可能不是特别快。有更快的方法吗?特别是,为了访问64位高位,我看不到合适的负载(SSE2中的低64位有负载)或shuffle指令(似乎没有" 64位shuffle")。
答案 0 :(得分:4)
如果我理解你的问题是正确的,这是一个简单的4x2转置(或2x4转置?)。
这是一个适合我的代码:
#include <iostream>
#include <immintrin.h>
using namespace std;
int main() {
__m128i a = _mm_set_epi64x(1, 11);
__m128i b = _mm_set_epi64x(2, 22);
__m128i c = _mm_set_epi64x(3, 33);
__m128i d = _mm_set_epi64x(4, 44);
__m256i ac = _mm256_castsi128_si256(a);
ac = _mm256_inserti128_si256(ac, c, 1); // {3, 33, 1, 11}
__m256i bd = _mm256_castsi128_si256(b);
bd = _mm256_inserti128_si256(bd, d, 1); // {4, 44, 2, 22}
__m256i high = _mm256_unpackhi_epi64(ac, bd);
__m256i low = _mm256_unpacklo_epi64(ac, bd);
uint64_t t[4];
_mm256_storeu_si256((__m256i*) t, high);
for (int i = 0; i < 4; ++i) {
cout << t[i] << endl;
}
_mm256_storeu_si256((__m256i*) t, low);
for (int i = 0; i < 4; ++i) {
cout << t[i] << endl;
}
return 0;
}
这应该编译成4条指令。