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

GCC优化级别大于0时输出近乎空的汇编文件问题求助

问题原因与解决办法

你遇到的这个问题其实很常见——GCC在优化级别大于0时,把你的integral_image函数彻底删掉了!

为什么会出现空汇编文件?

你的integral_image是静态函数(用static修饰),而且整个程序里没有任何地方调用它。GCC从-O1开始会启用死代码消除优化,对于这种未被使用的静态函数,编译器会判定它是“无用代码”,直接从编译结果中移除,所以最终的汇编文件里只剩一些文件标识和栈相关的注释,完全看不到函数的机器码。

解决方法(任选其一即可)

1. 添加函数调用(最推荐)

在代码里加上一个main函数,调用integral_image,哪怕是简单的测试调用:

#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#define HEIGHT 2000
#define WIDTH 1000

static unsigned int idx(unsigned int x, unsigned int y, unsigned int stride){
    return y * stride + x;
}

static void integral_image(const unsigned char * restrict in, unsigned int * restrict out){
    unsigned int row_sum = 0;
    unsigned char *newin = __builtin_assume_aligned(in, 16);
    unsigned int *newout = __builtin_assume_aligned(out, 16); // 修正类型不匹配问题
    for(unsigned int x = 0; x < WIDTH; ++x){
        row_sum += newin[x];
        newout[x] = row_sum;
    }
    for(unsigned int y = 1; y < HEIGHT; ++y){
        row_sum = 0;
        for(unsigned w = 0; w < WIDTH; w += 4){
            const unsigned int i1 = idx(w, y, WIDTH);
            const unsigned int old1 = idx(w, y - 1, WIDTH);
            const unsigned int i2 = idx(w + 1, y, WIDTH);
            const unsigned int old2 = idx(w + 1, y - 1, WIDTH); // 修正索引错误
            const unsigned int i3 = idx(w + 2, y, WIDTH);
            const unsigned int old3 = idx(w + 2, y - 1, WIDTH);
            const unsigned int i4 = idx(w + 3, y, WIDTH);
            const unsigned int old4 = idx(w + 3, y - 1, WIDTH);
            row_sum += newin[i1];
            newout[i1] = row_sum + newout[old1];
            row_sum += newin[i2];
            newout[i2] = row_sum + newout[old2];
            row_sum += newin[i3];
            newout[i3] = row_sum + newout[old3];
            row_sum += newin[i4];
            newout[i4] = row_sum + newout[old4];
        }
    }
}

int main() {
    // 分配测试内存并调用函数
    unsigned char *in = malloc(WIDTH * HEIGHT);
    unsigned int *out = malloc(WIDTH * HEIGHT * sizeof(unsigned int));
    if (in && out) {
        integral_image(in, out);
        free(in);
        free(out);
    }
    return 0;
}

编译时用gcc-7 -O2 -S thrash.c,就能看到完整的函数汇编代码了。另外我帮你修正了代码里的两个小问题:newout的类型应该是unsigned int*(和参数out匹配),以及old2的索引写错了,应该对应w+1的位置。

2. 强制保留未使用的静态函数

如果不想加main函数,可以给静态函数加上__attribute__((used))属性,告诉编译器这个函数必须被保留,即使没有被调用:

static void __attribute__((used)) integral_image(const unsigned char * restrict in, unsigned int * restrict out){
    // 函数实现不变
}

然后用gcc-7 -O2 -S thrash.c编译,就能在汇编文件里看到这个函数的代码了。

3. 用编译选项强制保留

也可以通过编译选项直接告诉GCC不要移除未使用的静态函数:

gcc-7 -O2 -fkeep-static-functions -S thrash.c

额外提示:查看向量化情况

除了看汇编代码,你还可以用GCC的向量化诊断选项,直接查看是否成功向量化:

gcc-7 -O2 -ftree-vectorize -fopt-info-vec-all thrash.c

这个命令会输出详细的向量化日志,告诉你哪些循环被向量化了,哪些没有,以及具体原因,比直接看汇编更直观。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 06:45:59