我有4个处理器,正在编译一个需要处理器的应用程序。我读到建议使用make
和-j4
开关用于OpenCV;我应该用-j8
代替吗?多处理器的优势是什么?
以上答案大部分都是正确的。然而,细节有些误导。例如,不需要为"管理线程"添加额外的作业(注意:make
实际上不是多线程的)。对于-j
来说,make
从来不会把自己算作一个作业,所以,正如惠更斯上面所说的,如果你说-j5
,你会得到5个正在运行的编译作业,而不是4个加上make。
大多数人使用[number of cores] + [some padding]的原因与make
或它需要什么无关,而是与编译器的性质有关。编译器实际上只是一个非常复杂的文本翻译工具:它读取一种形式的文本,并将其转换为另一种形式的"文本"(二进制)。其中很多(尤其是当语言变得更复杂时,比如c++)都需要大量CPU。但是它也需要大量的磁盘I/O。磁盘I/O很慢,所以当一个编译器等待来自磁盘的一些数据时,内核安排其他作业运行。这就是为什么你可以同时运行多个内核编译器的原因。
在您开始看到收益递减之前,您可以获得多大的-j
(您的构建实际上开始变慢,在某些时候,使用更多的-j
)完全取决于您的硬件,您正在进行的构建类型等。唯一能确定的方法就是实验。
但是,[number of cores]+[few]通常是一个很好的近似值。
正如你所说的-j
标志告诉make
,它被允许产生提供的"线程"数量。理想情况下,每个线程都在自己的核心/CPU上执行,这样您的多核/CPU环境就可以得到充分利用。
make
本身不编译源文件。这是由编译器(gcc)完成的。Makefile (make
的输入)包含一组目标。每个目标都有一组(在其他目标上的)依赖项和如何构建目标的规则。make
读取Makefile(s)并管理所有目标、依赖项和构建规则。除了编译源文件,您还可以使用make
执行任何可以由shell命令描述的任务。
如果将允许的线程数设置得太高,则不可能将每个线程调度到自己的核心上。需要额外的调度(上下文)开关来执行所有线程。这种额外的资源使用显然会导致性能降低。
有很多经验法则,但我想将总数设置为<number of cores> + 1
是最常见的。这背后的想法是,所有的核心都有自己的线程,并且有一个额外的管理线程来处理目标,这是接下来要构建的。
每个线程一个CPU加上一个管理器/加载器。因为从CPU的角度来看,执行磁盘操作的线程在技术上几乎是空闲的,所以在内核总数上增加一个。
如果CPU正在使用超线程,您可以安全地将每个核心计算为两个核心并将线程数量加倍,因此四核英特尔酷睿i7应该得到-j9(八个虚拟核心加上管理器)。在四核AMD上使用-j5
-j
选项仅用于加速应用程序构建,它决定make
可以为构建生成多少作业。您可以设置-j<nb core>
或更高的-j<nb-core * 1.5>
,以便编译可以并行进行。
对编译后的代码没有影响。
对于4核系统,您可以尝试make -j6
。如果make可以运行并行构建,它将同时启动多达6个编译过程(例如6个对gcc的调用)。