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

SSE编程求和报错求助:size=8时触发读取访问违例

SSE优化代码内存访问错误排查(size=8时崩溃)

嘿,我帮你找到了问题所在——你的代码触发了内存越界访问,还有个小语法错误得先修正。咱们一步步拆解:

核心崩溃原因:错误的存储指令导致内存越界

在你的sub_func_sse函数里,最后一步用了_mm_store_pd(ans + start_idx_ans, sum);,这个指令的作用是把__m128d寄存器里的2个double值连续写入内存。但你的需求是每个连续4个数的和只需要存1个double到ans_sse里,这就出问题了:

当size=8时,ans_sse的大小是8/4=2(也就是索引0和1):

  • 第一次调用sub_func_sse时,start_idx_ans=0,会写入ans_sse[0]和ans_sse[1],这时候还在合法内存范围内;
  • 第二次调用时,start_idx_ans=1,会写入ans_sse[1]和ans_sse[2],但ans_sse只分配到索引1,ans_sse[2]属于未分配的内存,直接触发了访问违规错误。

另外,你代码里的arith_t = double是非法语法,得改成typedef double arith_t;才能编译通过。

修正后的代码

我把问题点都修复了,还优化了一些细节(比如循环变量用size_t避免类型警告):

#include <iostream>
#include <immintrin.h>
#include <vector>
using namespace std;

typedef double arith_t;  // 修正语法错误

void init(arith_t *v, size_t size) {  // 去掉不必要的指针引用
    for (size_t i = 0; i < size; ++i) {  // 用size_t匹配参数类型,避免类型转换警告
        v[i] = i / 10.0;
    }
}

// SSE实现连续4个数求和
void sub_func_sse(arith_t *v, size_t size, int start_idx, arith_t *ans, size_t start_idx_ans) {
    __m128d first_part = _mm_loadu_pd(v + start_idx);
    __m128d second_part = _mm_loadu_pd(v + start_idx + 2);
    __m128d sum = _mm_add_pd(first_part, second_part);
    sum = _mm_hadd_pd(sum, sum);
    // 用_mm_store_sd存储单个double值,避免越界
    _mm_store_sd(ans + start_idx_ans, sum);
}

int main() {
    const size_t size = 8;
    arith_t *v = new arith_t[size];
    arith_t *ans_sse = new arith_t[size / 4];
    
    init(v, size);
    init(ans_sse, size / 4);
    
    int num_repeat = 1;
    arith_t total_time_sse = 0;
    
    for (int p = 0; p < num_repeat; ++p) {
        for (size_t idx = 0, ans_idx = 0; idx < size; idx += 4, ans_idx++) {
            sub_func_sse(v, size, idx, ans_sse, ans_idx);
        }
    }
    
    for (size_t i = 0; i < size / 4; ++i) {
        cout << ans_sse[i] << endl;
    }
    
    delete[] ans_sse;
    delete[] v;
    
    return 0;
}

额外提示

  • _mm_hadd_pd(sum, sum)执行后,寄存器的两个元素都是4个数的总和,所以只需要存其中一个就行,_mm_store_sd刚好用来存储单个double值;
  • 如果你的数组是内存对齐的(比如用_mm_malloc分配),可以把_mm_loadu_pd换成_mm_load_pd,能获得更好的性能;
  • 新手排查内存问题时,可以用Valgrind这类工具,能快速定位越界、泄漏等问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 09:10:35