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

使用+=运算符时C代码运行变慢的原因排查求助

问题描述

编辑:我删除了问题中的部分内容以避免混淆,感谢各位解答,我本应自行排查。

我正在编写一个用谱函数对信号重采样的程序,原本用C语言实现,但转成C++编码时遇到了性能问题。

以下是核心代码片段:test()函数通过指针传递数组调用test3(tmp),当我用+=运算符填充第一个函数的数组时,代码运行速度明显变慢。

注:我用零值做初始化和计算,且所有数组必须是double类型。

测试代码

#include <stdio.h>
#include <stdlib.h>

void test3(double *tmp);

void test() {
    double *tmp;
    int k;
    tmp = (double *) calloc(250 * 6, sizeof(double));
    for (k = 0; k < 1000; ++k)
        test3(tmp);
    free(tmp);
}

void test3(double *tmp) {
    int k;
    double *fx;
    double *srf;
    double *ptr;
    int p;
    int l;
    int c;
    double a;
    fx = (double *) calloc(2100 * 6, sizeof(double));
    srf = (double *) calloc(2100 * 250, sizeof(double));
    
    for (int k = 0; k < 2100 * 6; ++k)   fx[k] = 0;
    for (int k = 0; k < 2100 * 250; ++k) srf[k] = 0;
    
    ptr = (double *) calloc(250 * 6, sizeof(double));
    
    for (p = 0; p < 6; ++p) {
        for (l = 0; l < 250; ++l) {
            ptr[l + p*250] = 0.0;
            for (c = 0; c < 2100; ++c)
                ptr[l+p*250] += fx[c+p*2100] * srf[c+l*2100];
        }
    }
    for (k = 0; k < 250 * 6; ++k) tmp[k] = ptr[k];
    
    free(ptr);
    free(fx);
    free(srf);
}

int main(int argc, char *argv[]) {
    test();
    return 0;
}

编译与运行信息

编译命令:

gcc -O2 -o test test.c -lm

运行time ./test得到的结果:

./test_lut  3.84s user 0.11s system 98% cpu 4.008 total
优化方案
  • 删除冗余初始化:calloc会自动将分配的内存初始化为0,后续手动循环给fx、srf、ptr赋值0完全多余,直接删除这些循环能减少无意义的内存操作。
  • 减少动态内存分配次数:test3每次调用都要分配、释放三块大内存,1000次调用会产生3000次内存申请/释放操作,这是主要性能瓶颈之一。可以将fx、srf的分配移到test函数中,只做一次分配后传递给test3,避免重复开销。
  • 优化缓存命中率:当前srf[c+l*2100]的访问模式属于跨列访问(按二维数组逻辑),CPU缓存利用率极低。可以调整srf的存储顺序为c*250 + l,让内存访问符合连续存储规律,大幅提升缓存效率。
  • 移除中间数组ptr:直接在tmp上完成累加计算,省去ptr的分配、赋值和拷贝步骤,减少内存占用与数据拷贝开销。

修改后的核心代码示例:

void test() {
    double *tmp = (double *) calloc(250 * 6, sizeof(double));
    double *fx = (double *) calloc(2100 * 6, sizeof(double));
    double *srf = (double *) calloc(2100 * 250, sizeof(double));
    for (int k = 0; k < 1000; ++k)
        test3(tmp, fx, srf);
    free(tmp);
    free(fx);
    free(srf);
}

void test3(double *tmp, double *fx, double *srf) {
    int p, l, c;
    for (p = 0; p < 6; ++p) {
        for (l = 0; l < 250; ++l) {
            double sum = 0.0;
            for (c = 0; c < 2100; ++c)
                sum += fx[c+p*2100] * srf[c+l*2100];
            tmp[l + p*250] = sum;
        }
    }
}

内容的提问来源于stack exchange,提问作者Stéphane Guillaso

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 13:41:19