C 生成-j4或-j8

C 生成-j4或-j8,c,opencv,makefile,C,Opencv,Makefile,我有4个处理器,正在编译需要处理器的应用程序,我读到OpenCV建议使用带-j4开关的make,我应该使用-j8吗?多处理器make的优点是什么?选择-j仅用于加速应用程序构建,它确定生成时可以生成多少作业make。您可以设置-j或更高的-j,以便并行编译 它对编译后的代码没有影响 对于4核系统,您可以尝试make-j6。如果make可以运行并行构建,它将启动多达6个并行编译过程(例如,6个对gcc的调用)。正如您所说,-j标志告诉make允许生成所提供数量的“线程”。理想情况下,每个线程都在自

我有4个处理器,正在编译需要处理器的应用程序,我读到OpenCV建议使用带-j4开关的make,我应该使用-j8吗?多处理器make的优点是什么?

选择
-j
仅用于加速应用程序构建,它确定生成时可以生成多少作业
make
。您可以设置
-j
或更高的
-j
,以便并行编译

它对编译后的代码没有影响


对于4核系统,您可以尝试
make-j6
。如果make可以运行并行构建,它将启动多达6个并行编译过程(例如,6个对gcc的调用)。

正如您所说,
-j
标志告诉make允许生成所提供数量的“线程”。理想情况下,每个线程都在自己的核心/CPU上执行,因此您的多核心/CPU环境将得到充分利用

make
本身不编译源文件。这是由编译器(gcc)完成的。Makefile(make的输入)包含一组目标。每个目标都有一组依赖项(在其他目标上)以及如何构建目标的规则<代码>生成读取生成文件并管理所有目标、依赖项和生成规则。除了编译源文件外,您还可以使用
make
执行任何可以由shell命令描述的任务

如果您将允许的线程数设置得太高,则无法在其自己的核心上调度每个线程。需要额外的调度(上下文)开关才能让所有线程执行。这种额外的资源使用显然会导致性能降低


有多种经验法则,但我想将total amount设置为
+1
是最常见的。这背后的想法是,所有内核都有自己的线程,还有一个额外的管理线程来处理目标,下一个要构建。

每个线程一个CPU加上一个管理器/加载程序。由于从CPU的角度来看,执行磁盘操作的线程在技术上几乎处于空闲状态,因此在内核总数中添加一个线程


如果CPU使用超线程,您可以安全地将每个内核计算为两个内核并将线程数增加一倍,因此四核Intel core i7应获得-j9(八个虚拟内核加上管理器)。在四核AMD上使用-j5以上答案基本正确。然而,细节有点误导。例如,不需要为“管理线程”添加额外的作业(注意:
make
实际上不是多线程的)
make
-j
中从不将自己算作作业,因此,正如惠更斯在上面所说的,如果你说
-j5
你将运行5个编译作业,而不是4个加上make

大多数人使用[number of core]+[some padding]的原因与
make
或它需要什么无关,而是与编译器的性质有关。编译器实际上只是一个非常复杂的文本翻译工具:它以一种形式读入文本,然后以另一种形式将其转换为“文本”(二进制)。其中很多(尤其是当您的语言变得更复杂时,比如C++),需要大量的CPU。但是它也需要大量的磁盘I/O。磁盘I/O速度很慢,因此当一个编译器正在等待来自磁盘的一些数据时,内核会安排其他作业运行。这就是为什么在同一时间运行的内核编译数量可以超过内核编译数量的原因

在你开始看到收益递减(你的构建实际上开始变慢,在某一点上,有更多的
-j
)之前,你能得到的
-j
的确切大小完全取决于你的硬件、你正在进行的构建的类型等。唯一确定的方法是实验


然而,[芯数]+[少数]通常是一个很好的近似值。

另见Tl;博士:
make-j$(nproc)
维格解释得很好。非常感谢您的回答。非常好的总结!感谢@madscitist如果要构建的文件非常大,[cores]+[something>0]可能会导致瓶颈,因为一旦所有IO操作完成,每个线程都会非常容易被应用。我使用-j cores作为最大值。运行
vmstat
并观察阻塞值非常有用。编译器选项也可能会影响这一点。Ie,-O0比-O3占用更少的CPU,因此对于未优化的构建,I/O更重要。我想知道依赖关系信息可以用来优化磁盘缓存吗?及;修改
benchmark.sh
并更改
NPROC
变量。代码结构是合成的,而不是真实的构建,但是这是实验和评估的一个很好的起点。我认为值得补充的是,这两方面都不难衡量。一个编译足够多,尝试cores+2和cores-2应该很容易。尝试是很重要的,因为IO子系统的速度在过去的5年里发生了根本性的变化。