c - 编译大量代码生成的源文件的任何提示?

标签 c gcc compilation clang

我正在尝试编译生成来自大 eng 的 C 代码。楷模。生成的代码与人们编写的不同,有许多展开的循环、大量使用宏、手动索引的巨大数组,最重要的是源文件很大(> 1e6 行)。
使用 O2 编译这些源文件时或 O3 ,我的编译时间变得难以控制: 10-30 分钟 每个文件。这适用于 Clang 和 GCC。我不能很好地遵循生成的汇编代码,所以我不确定优化的质量。可以通过不生成调试信息或关闭警告来减少编译时间,但与关闭优化相比,这些时间很小。在运行时间方面,O0 之间存在明显差异。和 O2 ,所以我不能证明这样做是合理的。使用 -ftime-trace 编译时,我可以看到 Clang 前端负责 > 90% 的时间。根据htop,进程不受内存限制,似乎完全受CPU 限制。 .
是否有一些预处理可以改善编译时间?将源文件分成更小的块会提高性能,为什么?编译器是否设计用于处理这些巨大的源文件?是否还有我应该注意的其他编译选项?
令人惊讶的是,Windows 上的 MSVC 带有 /O2只需要 Clang 和 GCC 花费的一小部分时间。
编译器参数示例:clang -m64 -Wno-everything -c -D_GNU_SOURCE -DMATLAB_MEX_FILE -ftime-report -DFMI2_FUNCTION_PREFIX=F2_Simulations_SteadyState_SteadyState2019MPU_ -DRT -I/opt/matlab/r2017b/extern/include -I/opt/matlab/r2017b/simulink/include -I/mnt/vagrant_shared/<path>/Source -I/mnt/vagrant_shared/<path>/export -fexceptions -fPIC -fno-omit-frame-pointer -pthread -O0 -DNDEBUG -std=c99 /mnt/vagrant_shared/<path>/some_file.c -o /mnt/vagrant_shared/<path>/some_obj.obj平台:在虚拟机 VM 上运行的 CentOS 7。 Clang 7、GCC 4.8(由于其他要求,我坚持使用这些旧版本)。

最佳答案

根据@AProgrammer 提出的建议,用包含优化的子集替换 -O2 会产生实质性的编译时改进,运行时差异可忽略不计。

具体来说,我排除 :
-fcode-hoisting -fdevirtualize-speculatively -fexpensive-optimizations -fipa-bit-cp -fipa-icf -fipa-ra -fipa-vrp -fisolate-erroneous-paths-dereference -flra-remat -freorder-blocks-algorithm=stc -fstore-merging -fipa-reference -fipa-reference-addressable -fshrink-wrap-separate -fssa-backprop -fssa-phiopt
无论如何,其中一些仅适用于 C++。生成的编译速度提高了约 3 倍。 -O3 中可能包含其他选项可以包含很少的编译时损失。

其他人建议 GCC 和 Dymola 都推荐 -O1作为编译时和运行时性能之间的良好折衷。使用一些额外的 -f顶部的选项 -O1将是一个很好的方法,可以在 future 证明这一点,以防止不同 GCC 选项的影响/好处的变化。

此外,如预期的那样,通过将源文件分解成更小的块,总编译时间(编译和链接)会变得更糟。

关于c - 编译大量代码生成的源文件的任何提示?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59041227/

相关文章:

c - 为什么我们甚至不允许在 switch-case 中使用全局 const 限定变量?IBM 支持门户提示我们可以

c - 通过UDP协议(protocol)发送巨大的(大约40K字节)数据,怎么可能呢?

c++ - memcpy 进程安全吗?

c++ - 有没有办法在不修改每个源文件的情况下在每个编译单元中包含一个头文件?

c++ - 一种为 c 执行 c++ "typedef struct foo foo;"的方法

mysql - 如何在查询 SQL oracle 中正确编写别名

C错误: assignment to expression with array type

C 变量和指针

c - 用 C 语言构建静态库

java - 使用两个不同的泛型参数调用泛型函数仍然可以编译