_mm_load_si128 以相反的顺序加载数据
_mm_load_si128 loads data in reverse order
我正在编写一个带有 SSE2 内在函数的 C 函数来比较 4 个 32 位整数并检查哪些大于零,并以 16 位掩码的形式给出结果。我正在使用以下代码来执行此操作
#include <x86intrin.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
static void cmp_example(void) {
const uint32_t byte_vals[] = {0, 5, 0, 3};
__m128i got_data = _mm_load_si128((__m128i const*)byte_vals);
__m128i cmp_data = _mm_setzero_si128();
__m128i result = _mm_cmpgt_epi32 (got_data, cmp_data);
int mask_result = _mm_movemask_epi8(result);
printf("Result 0x%x\n", mask_result & 0xFFFF);
}
但是,当我编译 运行 时,它会打印 0xf0f0
。我希望结果遵循从内存加载的相同顺序。为了进一步检查,我添加了一些调试语句,如下所示:
const uint32_t byte_vals[] = {0, 5, 0, 3};
__m128i got_data = _mm_load_si128((__m128i const*)byte_vals);
printf("0x%llx 0x%llx\n", got_data[0], got_data[1]);
__m128i cmp_data = _mm_setzero_si128();
__m128i result = _mm_cmpgt_epi32 (got_data, cmp_data);
printf("0x%llx 0x%llx\n", result[0], result[1]);
int mask_result = _mm_movemask_epi8(result);
printf("Result 0x%x\n", mask_result & 0xFFFF);
这个运行打印
0x500000000 0x300000000
0xffffffff00000000 0xffffffff00000000
Result 0xf0f0
因此,这里的罪魁祸首似乎是 _mm_load_si128
.
基于此,如何让 _mm_load_si128
以与内存中布局相同的顺序加载数据?
_mm_load_si128
以小端格式加载数据。字 0 至少在概念上指向 xmm 寄存器中的元素 0。
但是当这些值作为十六进制值打印时,它们是以大端格式打印的。 xmm 寄存器 got_data[0]
的第一个 int64_t 元素包含字节流 00 00 00 00 05 00 00 00
,即 0x(000000)0500000000ull.
根据上下文,值必须从左到右或从右到左阅读。掩码的第 0 个半字节 (0x000F) 对应于 result
.
的第 0 个字
我正在编写一个带有 SSE2 内在函数的 C 函数来比较 4 个 32 位整数并检查哪些大于零,并以 16 位掩码的形式给出结果。我正在使用以下代码来执行此操作
#include <x86intrin.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
static void cmp_example(void) {
const uint32_t byte_vals[] = {0, 5, 0, 3};
__m128i got_data = _mm_load_si128((__m128i const*)byte_vals);
__m128i cmp_data = _mm_setzero_si128();
__m128i result = _mm_cmpgt_epi32 (got_data, cmp_data);
int mask_result = _mm_movemask_epi8(result);
printf("Result 0x%x\n", mask_result & 0xFFFF);
}
但是,当我编译 运行 时,它会打印 0xf0f0
。我希望结果遵循从内存加载的相同顺序。为了进一步检查,我添加了一些调试语句,如下所示:
const uint32_t byte_vals[] = {0, 5, 0, 3};
__m128i got_data = _mm_load_si128((__m128i const*)byte_vals);
printf("0x%llx 0x%llx\n", got_data[0], got_data[1]);
__m128i cmp_data = _mm_setzero_si128();
__m128i result = _mm_cmpgt_epi32 (got_data, cmp_data);
printf("0x%llx 0x%llx\n", result[0], result[1]);
int mask_result = _mm_movemask_epi8(result);
printf("Result 0x%x\n", mask_result & 0xFFFF);
这个运行打印
0x500000000 0x300000000
0xffffffff00000000 0xffffffff00000000
Result 0xf0f0
因此,这里的罪魁祸首似乎是 _mm_load_si128
.
基于此,如何让 _mm_load_si128
以与内存中布局相同的顺序加载数据?
_mm_load_si128
以小端格式加载数据。字 0 至少在概念上指向 xmm 寄存器中的元素 0。
但是当这些值作为十六进制值打印时,它们是以大端格式打印的。 xmm 寄存器 got_data[0]
的第一个 int64_t 元素包含字节流 00 00 00 00 05 00 00 00
,即 0x(000000)0500000000ull.
根据上下文,值必须从左到右或从右到左阅读。掩码的第 0 个半字节 (0x000F) 对应于 result
.