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

C++23 experimental simd存取数值返回随机结果求助

问题:std::experimental::simd 类型访问出现异常输出

编写了一段测试代码复现std::experimental::simd的异常问题,代码如下:

#include <experimental/simd>

namespace stdx = std::experimental;

using vfloat4 = stdx::fixed_size_simd<float, 4>;
using vint4 = stdx::fixed_size_simd<int, 4>;

inline void print_vint4(vint4 vi4)
{
    printf("%i %i %i %i\n", vi4[0], vi4[1], vi4[2], vi4[3]);
}

int main()
{
    vint4 _v = 4;
    printf(">> %i\n", _v[0]);
    printf(">> %i\n", _v[0]);
    print_vint4(_v);
    return 1;
}

运行后输出示例:

>> 1233123648
>> 1233123664
1233123568 1233123552 1233123536 1233123520

现象说明:

  • 两条完全相同的printf语句输出数值不同,且每次运行结果随机变化(有时正有时负)
  • 将vint4替换为vfloat4并使用%f格式符时,所有输出数值均为0

环境信息:

  • 编译器:GCC 14.2.0(运行于MSYS2)
  • 操作系统:Windows 10 64位
  • CPU:Intel i5 12代 x86_64

问题原因与解决方法

原因

stdx::fixed_size_simd<T, N>的operator[]返回的是代理对象(而非直接的T类型值),而printf是可变参数函数,无法正确识别和处理这种代理类型,从而触发未定义行为,导致输出异常。

解决方法

访问simd元素时,需要显式将代理对象转换为对应的标量类型,或者将simd数据拷贝到普通数组后再输出:

方法1:显式转换为标量类型

修改代码中访问元素的部分,用static_cast转换为目标类型:

#include <experimental/simd>

namespace stdx = std::experimental;

using vfloat4 = stdx::fixed_size_simd<float, 4>;
using vint4 = stdx::fixed_size_simd<int, 4>;

inline void print_vint4(vint4 vi4)
{
    printf("%i %i %i %i\n",
           static_cast<int>(vi4[0]),
           static_cast<int>(vi4[1]),
           static_cast<int>(vi4[2]),
           static_cast<int>(vi4[3]));
}

int main()
{
    vint4 _v = 4;
    printf(">> %i\n", static_cast<int>(_v[0]));
    printf(">> %i\n", static_cast<int>(_v[0]));
    print_vint4(_v);
    
    // 测试vfloat4的情况
    vfloat4 _fv = 4.0f;
    printf(">> %f\n", static_cast<float>(_fv[0]));
    return 0;
}

方法2:拷贝到普通数组输出

利用stdx::copy_from将simd数据拷贝到普通数组,再输出数组元素:

#include <experimental/simd>
#include <cstdio>

namespace stdx = std::experimental;

using vint4 = stdx::fixed_size_simd<int, 4>;

inline void print_vint4(vint4 vi4)
{
    int arr[4];
    stdx::copy_from(vi4, arr);
    printf("%i %i %i %i\n", arr[0], arr[1], arr[2], arr[3]);
}

int main()
{
    vint4 _v = 4;
    int val;
    stdx::copy_from(_v[0], &val); // 单个元素拷贝
    printf(">> %i\n", val);
    printf(">> %i\n", val);
    print_vint4(_v);
    return 0;
}

修改后运行,即可得到正确的输出:

>> 4
>> 4
4 4 4 4

内容的提问来源于stack exchange,提问作者person the human

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 19:55:07