You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

_mm_store_si128/_mm_storeu_si128存储字节顺序异常的修复咨询

问题

我有一个signed char数组:

const signed char From[] = {
    0b00000000, 0b00000001, 0b00000010, 0b00000011,
    0b00000100, 0b00000101, 0b00000110, 0b00000111,
    0b00001000, 0b00001001, 0b00001010, 0b00001011,
    0b00001100, 0b00001101, 0b00001110, 0b00001111,
};

需要将数组中的字符存入__m128i向量,再通过_mm_store_si128把向量内容存储到std::uint32_t Schedule[4]数组中。当前实现如下:

const __m128i Chars = _mm_set_epi8 (
    From[0],
    From[1],
    From[2],
    From[3],
    From[4],
    From[5],
    From[6],
    From[7],
    From[8],
    From[9],
    From[10],
    From[11],
    From[12],
    From[13],
    From[14],
    From[15]
);
_mm_store_si128((__m128i*)&Schedule[Kter], SettedLines4);

但存储后Schedule的字节顺序不符合预期(疑似位或字节错乱),通过自定义的to_binary函数验证了该问题。完整代码如下:

# include <x86intrin.h>
# include <iostream>
# include <cstdint>

template<typename Type>
[[ nodiscard ]] std::string to_binary(Type Data) noexcept
{
    std::string Result = "";

    std::uint64_t CurrentBit = 8 * sizeof Data;
    while(CurrentBit--)
        Result += ((Data >> CurrentBit) & 1) == 0 ? "0" : "1";

    return Result;
}

int main(void)
{
    std::uint32_t Schedule[4];
    const signed char From[] = {
        0b00000000, 0b00000001, 0b00000010, 0b00000011,
        0b00000100, 0b00000101, 0b00000110, 0b00000111,
        0b00001000, 0b00001001, 0b00001010, 0b00001011,
        0b00001100, 0b00001101, 0b00001110, 0b00001111,
    };

    const __m128i v = _mm_set_epi8 (
        From[0],
        From[1],
        From[2],
        From[3],
        From[4],
        From[5],
        From[6],
        From[7],
        From[8],
        From[9],
        From[10],
        From[11],
        From[12],
        From[13],
        From[14],
        From[15]
    );

    _mm_store_si128((__m128i*)&Schedule[0], v);
    std::cout << to_binary(Schedule[0]) << std::endl;
    std::cout << to_binary(Schedule[1]) << std::endl;
    std::cout << to_binary(Schedule[2]) << std::endl;
    std::cout << to_binary(Schedule[0]) << std::endl;
}

请问如何修复该问题,以获得预期的字节顺序?


解决方法

问题根源

  1. _mm_set_epi8的参数逻辑:这个函数的第一个参数对应向量的最高地址字节(128位中的第15个字节,从0开始计数),最后一个参数对应向量的最低地址字节(第0个字节)。你当前把From[0]放在第一个参数位置,会导致它被放到向量的高地址端,和预期顺序完全相反。
  2. 存储映射的字节顺序:_mm_store_si128按内存地址顺序存储向量字节,结合上面的参数顺序错误,最终Schedule数组的字节顺序会完全颠倒。

修复方式

有两种简洁的修复方案:

方案一:反转_mm_set_epi8的参数顺序

将From数组的元素从最后一个到第一个传入函数,让From[0]对应向量的最低地址字节:

const __m128i v = _mm_set_epi8 (
    From[15], From[14], From[13], From[12],
    From[11], From[10], From[9],  From[8],
    From[7],  From[6],  From[5],  From[4],
    From[3],  From[2],  From[1],  From[0]
);

存储后,Schedule[0]会是0x03020100(二进制00000011000000100000000100000000),Schedule[1]是0x07060504,以此类推,符合预期的字节拼接顺序。

方案二:直接加载数组到向量

如果From数组的内存布局已经是你想要的顺序,用_mm_loadu_si128(或_mm_load_si128,若数组内存对齐)直接加载整个数组,避免手动传参的错误:

const __m128i v = _mm_loadu_si128((const __m128i*)From);

这种方式直接按内存顺序把From的16个字节加载到向量中,存储后Schedule的字节顺序与From完全一致,代码更简洁且不易出错。

验证效果

修复后运行代码,Schedule的输出会符合预期:

  • Schedule[0]:00000011000000100000000100000000
  • Schedule[1]:00000111000001100000010100000100
  • Schedule[2]:00001011000010100000100100001000
  • Schedule[3]:00001111000011100000110100001100

内容的提问来源于stack exchange,提问作者faust403

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 00:20:55