快速的问题:允许g ++生成自身的多个实例以便更快地编译大型项目(例如,对于多核CPU一次是4个源文件)的编译器标志是什么?
make -j
几乎总会带来一些改善。
快速的问题:允许g ++生成自身的多个实例以便更快地编译大型项目(例如,对于多核CPU一次是4个源文件)的编译器标志是什么?
make -j
几乎总会带来一些改善。
Answers:
您可以使用make-使用gnu使它成为-j标志(这在单处理器计算机上也有帮助)。
例如,如果要从make进行4个并行作业:
make -j 4
您也可以在管道中运行gcc
gcc -pipe
这将流水线化编译阶段,这也将有助于保持内核繁忙。
如果您还可以使用其他机器,则可以签出 distcc,这也会将编译出来的内容也提供给这些计算机。
-j
争辩
没有这样的标志,并且有一个与Unix理念背道而驰的原则,即每个工具只能执行一个功能并很好地执行它。从概念上讲,生成编译器进程是构建系统的工作。您可能正在寻找的是GNU make的-j(jobs)标志,
使-j4
或者,您可以使用pmake或类似的并行make系统。
如果使用make,请发出-j
。来自man make
:
-j [jobs], --jobs[=jobs] Specifies the number of jobs (commands) to run simultaneously. If there is more than one -j option, the last one is effective. If the -j option is given without an argument, make will not limit the number of jobs that can run simultaneously.
最值得注意的是,如果您要编写脚本或确定可用内核的数量(取决于您的环境,并且如果您在许多环境中运行,则可能会发生很大变化),则可以使用无处不在的Python函数 cpu_count()
:
https://docs.python.org/3/library/multiprocessing.html#multiprocessing.cpu_count
像这样:
make -j $(python3 -c 'import multiprocessing as mp; print(int(mp.cpu_count() * 1.5))')
如果您问为什么1.5
我会在上面的评论中引用用户虚假噪声:
1.5的数字是由于指出的I / O绑定问题。这是一个经验法则。大约1/3的作业将等待I / O,因此其余的作业将使用可用的内核。大于核心的数字更好,甚至可以高达2倍。
make -j`nproc`
with nproc
。
make -j $(( $(nproc) + 1 ))
确保将空格放在我的位置)。
nproc
不可用的系统(例如在manylinux1
容器中)上使用python的不错建议,它通过避免运行yum update
/ 来节省更多时间yum install
。
distcc还可以不仅在当前计算机上,而且还可以在服务器场中安装了distcc的其他计算机上分发编译。
GNU并行
我当时正在制定综合编译基准,因此不必费心编写Makefile,因此我使用了:
sudo apt-get install parallel
ls | grep -E '\.c$' | parallel -t --will-cite "gcc -c -o '{.}.o' '{}'"
说明:
{.}
接受输入参数并删除其扩展名-t
打印出正在运行的命令,以使我们了解进度--will-cite
如果您使用软件发布结果,则删除引用该软件的请求...parallel
非常方便,我什至可以自己做一个时间戳检查:
ls | grep -E '\.c$' | parallel -t --will-cite "\
if ! [ -f '{.}.o' ] || [ '{}' -nt '{.}.o' ]; then
gcc -c -o '{.}.o' '{}'
fi
"
xargs -P
也可以并行运行作业,但是执行扩展操作或使用它来运行多个命令要不那么方便:通过xargs调用多个命令
在以下位置询问了并行链接:链接时gcc可以使用多个内核吗?
TODO:我想我在某处读到可以将编译简化为矩阵乘法,因此也许还可以加快大文件的单文件编译速度。但是我现在找不到参考。
已在Ubuntu 18.10中测试。