【问题标题】:How can I compile this very big, but boring C source?我如何编译这个非常大但很无聊的 C 源代码?
【发布时间】:2015-11-19 22:07:11
【问题描述】:

我的代码中的中心函数如下所示(其他都是普通的输入和输出):

const int n = 40000;

double * foo (double const * const x)
{
    double * y = malloc (n*sizeof(double));

    y[0] = x[0] + (0.2*x[1]*x[0] - x[2]*x[2]);
    y[1] = x[1] + (0.2*x[1]*x[0] - x[2]*x[2]);
    // …
    // 39997 lines of similar code
    // that cannot be simplified to fewer lines
    // …
    y[40000] = 0.5*x[40000] - x[12345] + 5*x[0];

    return y;
}

为了这个问题的目的,假设像这样(或非常相似)对这 40000 行进行硬编码是非常必要的。所有这些行仅包含具有固定数字和x 条目的基本算术运算(平均每行四十个);没有调用任何函数。源文件的总大小为 14MB。

在尝试编译此代码时,我面临编译器大量使用内存的问题。我可以让 Clang 用 -O0 编译它(只需要 20 秒),但我使用 GCC(即使使用 -O0)或 -O1 都失败了。

虽然在代码端或全局范围内几乎没有什么可以优化的(即,通过以另一种顺序计算各个行),但我相信编译器会找到一些可以在局部范围内优化的东西(例如,计算 y[0]y[1] 所需的括号内的项。

我的问题是:

  • 是否有一些编译器标志只激活不需要太多额外内存的优化?
  • 是否有其他方法可以使编译器更好地处理此源代码(不会损失比通过优化获得的速度更多的速度)?

【问题讨论】:

  • 注意:你有什么理由让xconst,而不是它指向的数组?
  • 把它分成 4 个文件,每个文件 10000 行?
  • 出于好奇,您的计算机(托管 gcc/clang)有多少内存?
  • @Foon:在一种情况下,编译器使用了我所有的 4GB RAM 和几乎所有的另外 8GB 交换空间。
  • 您能否详细说明每个表达式的复杂程度?我编写了一个 python 脚本来生成看起来与您所包含的相似的样本......我的源代码“仅”2.7 MB,使用 gcc -O2 “仅”编译需要 4 分钟(使用 gcc 编译,没有指定 O 标志只需要 20.7秒)

标签: c compilation compiler-optimization compiler-flags


【解决方案1】:

The following comment by Lee Daniel Crocker 解决了这个问题:

我怀疑您遇到的限制是单个堆栈帧/块/函数所需的结构的大小。试着把它分解成 100 个函数,每个函数 400 行,看看效果是否更好。

当使用每个 100 行的函数(并连续调用所有函数)时,我得到了一个可以用-O2 毫无问题地编译的程序。

【讨论】:

  • 我看不出这是如何回答这个问题的,因为原始问题包含以下陈述:假设出于这个问题的目的,像这样(或非常相似)对这 40000 行进行硬编码是真的很有必要。所有这些行仅包含具有固定数字和 x 条目的基本算术运算(平均每行 40 个);没有函数被调用。
【解决方案2】:

您可以根据需要add swap space 让编译器在启用优化的情况下编译代码。使用这种技术,编译过程会变得慢很多。但是,编译器可用的内存量仅受虚拟地址空间大小的限制。另一个不太方便的选择是安装更多 RAM。还要确保运行编译器的进程对它可以分配的内存量没有限制。关于编译器标志,我认为没有标志可以用来直接控制编译器的内存使用,让编译器自行调整到指定的限制。

【讨论】:

    【解决方案3】:

    把它写在汇编里。

    我假设你有一个生成这个 C 文件的工具。为什么不让它吐出汇编代码呢?

    【讨论】:

    • 除了必须学习组装之外,这可能不会带来任何优化方面的优势。
    • 也许您可以让 clang 为您生成程序集并执行优化,然后将其与使用 GCC 的项目的其余部分链接。
    • 编写自定义程序集(如果正确完成)将在优化方面带来巨大优势。
    • @user3386109:只有如果正确完成。这就是 99.9% 的“优化布道者”严重高估自己能力的地方。
    • @user3386109:当然,我会手动优化几兆字节的汇编。
    猜你喜欢
    • 2016-04-18
    • 2016-07-19
    • 2014-06-29
    • 1970-01-01
    • 2015-05-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-25
    相关资源
    最近更新 更多