首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么GCC只能在int大小是编译时常数的情况下进行循环交换优化?

为什么GCC只能在int大小是编译时常数的情况下进行循环交换优化?
EN

Stack Overflow用户
提问于 2020-04-03 16:29:34
回答 1查看 615关注 0票数 3

当我编译这个片段(使用-Ofast -floop-nest-optimize)时,gcc生成按源顺序遍历数组的程序集。

但是,如果我取消对// n = 32767行的注释,并将any编号分配给n,则会将索引顺序更改为x[i * n + j]。以连续行-主要顺序遍历内存比跨列遍历要友好得多。

代码语言:javascript
复制
float matrix_sum_column_major(float* x, int n) {
    // n = 32767;
    float sum = 0;
    for (int i = 0; i < n; i++)
        for (int j = 0; j < n; j++)
            sum += x[j * n + i];
    return sum;
}

论哥德波特

为什么GCC或clang不能使用运行时变量int 回路交换 呢?实际代码通常不会显式地声明大小。

PD:我用gcc和clang-9的不同版本试过了,这两者似乎都发生了。

PD2:即使我使x成为函数内部的局部变量malloc,它仍然会发生。

EN

回答 1

Stack Overflow用户

发布于 2020-04-12 17:46:26

编译器通常将他们的工作(并且应该集中精力)集中在对效率感兴趣的程序员可能使用的构造可以被其他结构所取代的地方,这些构造在任何情况下都很容易被证明是等价的,而这些构造应该是重要的。如果n是常量,编译器可以确定将在循环中使用的数组索引的确切集合,然后确定如何处理所有这些索引。如果n不是常数,编译器可能能够确定当n为正数时,代码将使用从0n*n-1的所有索引,但这可能需要付出更多的努力。“clang”的作者可能会在这种情况下做出这样的决定,如果他们足够努力的话,但是他们可能认为这种努力是不值得的。

请注意,如果代码将比任何其他代码更多地使用n的一些特定值,让代码显式地检查这些值并使用为它们量身定制的循环,那么编译器可能能够为这些循环生成比可以使用任意n的循环更高效的代码。由于许多现实世界中的问题可能有一些比其他问题更多使用的n值,所以编译器编写人员假设对性能感兴趣的程序员可能会使用这种特殊的循环,并且花费一定的精力来改进任意的-n循环可能比在其他地方花费同样的精力带来的好处更少。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61016358

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档