用 g + + 使用多个核进行编译

快速提问: 为了更快地编译大型项目,允许 g + + 自身产生多个实例的编译器标志是什么(例如,对于一个多核 CPU,一次4个源文件) ?

180391 次浏览

make会为你做这个。研究手册页中的 -j-l开关。我不认为 g++是可并行的。

我对 g + + 不是很确定,但是如果你正在使用 GNU Make,那么“ Make-j N”(其中 N 是可以创建的线程数)将允许 Make 同时运行多个 g + + 作业(只要文件不相互依赖)。

没有这样的标志,有一个运行与 Unix 的哲学,让每个工具只执行一个功能,并执行得很好。从概念上讲,生成编译器进程是构建系统的工作。您可能正在寻找的是 GNU make 的-j (jobs)标志

make -j4

Or you can use pmake or similar parallel make systems.

您可以使用 make-with gnu make it is the-j 标志(这在单处理器计算机上也很有帮助)来实现这一点。

例如,如果您希望 make 中有4个并行作业:

make -j 4

还可以在具有

gcc -pipe

这将管道编译阶段,这也将有助于保持核心忙碌。

如果您还有其他可用的计算机,您可以签出 Distcc,它也会将编译外包给这些计算机。

人们提到了 make,但是 bjam也支持类似的概念。使用 bjam -jx指示 bjam 构建到 x并发命令。

我们在 Windows 和 Linux 上使用相同的构建脚本,并且在这两个平台上使用这个选项可以减少一半的构建时间。不错嘛。

Distcc 还可以用于不仅在当前计算机上分发编译,而且还可以在安装 distcc 的场中的其他计算机上分发编译。

如果使用 make,则与 -j发生问题:

  -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倍。

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中测试。