我如何编译这个非常大但无聊的 C 源代码?
How can I compile this very big, but boring C source?
我代码中的核心函数如下所示(其他一切都是原始输入和输出):
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]
所需的括号项)。
我的问题是:
- 是否有一些编译器标志仅激活不需要太多额外内存的优化?
- 是否有其他一些方法可以使编译器更好地处理此源代码(不会损失比通过优化获得的速度更多的速度)?
用汇编写。
我假设您有生成此 C 文件的工具。为什么不让它吐出汇编代码呢?
您可以 add swap space 尽可能多地让编译器在启用优化的情况下编译代码。使用这种技术,编译过程会变得更慢。但是,编译器可用的内存量仅受虚拟地址大小的限制 space。另一个不太方便的选择是安装更多 RAM。还要确保编译器所在的进程 运行 对其可以分配的内存量没有限制。关于编译器标志,我认为没有标志可以用来直接控制编译器的内存使用,让编译器自行调整到指定的限制。
The following comment 作者 Lee Daniel Crocker 解决了这个问题:
I suspect the limit you're running into is the size of the structures needed for a single stack frame/block/function. Try breaking it up into, say, 100 functions of 400 lines each and see if that does better.
当每个函数使用 100 行(并连续调用所有函数)时,我获得了一个可以用 -O2
毫无问题地编译的程序。
我代码中的核心函数如下所示(其他一切都是原始输入和输出):
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]
所需的括号项)。
我的问题是:
- 是否有一些编译器标志仅激活不需要太多额外内存的优化?
- 是否有其他一些方法可以使编译器更好地处理此源代码(不会损失比通过优化获得的速度更多的速度)?
用汇编写。
我假设您有生成此 C 文件的工具。为什么不让它吐出汇编代码呢?
您可以 add swap space 尽可能多地让编译器在启用优化的情况下编译代码。使用这种技术,编译过程会变得更慢。但是,编译器可用的内存量仅受虚拟地址大小的限制 space。另一个不太方便的选择是安装更多 RAM。还要确保编译器所在的进程 运行 对其可以分配的内存量没有限制。关于编译器标志,我认为没有标志可以用来直接控制编译器的内存使用,让编译器自行调整到指定的限制。
The following comment 作者 Lee Daniel Crocker 解决了这个问题:
I suspect the limit you're running into is the size of the structures needed for a single stack frame/block/function. Try breaking it up into, say, 100 functions of 400 lines each and see if that does better.
当每个函数使用 100 行(并连续调用所有函数)时,我获得了一个可以用 -O2
毫无问题地编译的程序。