我想尽快编译。去搞清楚。并希望自动选择选项后面的数字-j
。我如何以编程方式选择该值,例如在 shell 脚本中?
的输出是否nproc
等于我可用于编译的线程数?
make -j1
make -j16
答案1
nproc
给出可用 CPU 核心/线程的数量,例如8 在支持双向 SMT 的四核 CPU 上。
make
使用该选项可以并行运行的作业数量-j
取决于多种因素:
- 可用内存量
make
每个作业使用的内存量make
作业受 I/O 或 CPU 限制的程度
make -j$(nproc)
是一个不错的起点,但您通常可以使用更高的值,只要您不耗尽可用内存并开始抖动。
对于真正快速的构建,如果您有足够的内存,我建议使用 a tmpfs
,这样大多数作业将受 CPU 限制,并且make -j$(nproc)
会尽可能快地运行。
答案2
最直接的方法是nproc
像这样使用:
make -j`nproc`
该命令nproc
将返回计算机上的核心数。通过将其包装在刻度中,该nproc
命令将首先执行,返回一个数字,该数字将被传递到make
.
您可能有一些轶事经验,即执行 core-count + 1 会导致更快的编译时间。这更多地与 I/O 延迟、其他资源延迟和其他资源可用性限制等因素有关。
要使用 执行此操作nproc+1
,请尝试以下操作:
make -j$((`nproc`+1))
答案3
不幸的是,即使同一构建的不同部分也可能是具有冲突的 j 因子值的最佳选择,具体取决于正在构建的内容、方式、当时哪些系统资源是瓶颈、构建机器上还发生了什么、发生了什么网络(如果使用分布式构建技术)、构建中涉及的许多缓存系统的状态/位置/性能等。
编译 100 个微小的 C 文件可能比编译一个巨大的 C 文件更快,反之亦然。构建小型高度复杂的代码可能比构建大量直接/线性代码慢。
即使构建的上下文也很重要 - 使用针对专用服务器上的构建进行优化的 aj 因子,针对独占的、非重叠的构建进行微调,当开发人员在同一共享服务器上并行构建时,可能会产生非常令人失望的结果(每个此类构建可能需要更多时间)时间比所有序列化的时间总和还要长),或者在具有不同硬件配置或虚拟化的服务器上。
还有构建规范的正确性方面。非常复杂的构建可能存在竞争条件,导致间歇性构建失败,其发生率可能随着 j 因子的增加或减少而发生很大变化。
我可以继续说下去。关键是你必须实际评估你的内置你的背景您想要优化 j 因子。 @Jeff Schaller 的评论适用:迭代直到找到最适合的。就我个人而言,我会从 nproc 值开始,首先尝试向上,只有当向上尝试显示立即退化时才向下尝试。
首先在假定相同的环境中测量几个相同的构建可能是一个好主意,只是为了了解测量的可变性 - 如果太高,可能会危及您的整个优化工作(20% 的可变性将完全掩盖 10% 的改进/ j 因子搜索中的退化读数)。
最后,恕我直言,最好使用(自适应)工作服务器如果受支持且可用而不是固定的 j 因子 - 它可以在更广泛的上下文中始终提供更好的构建性能。
答案4
如果您想编写make
命令来使用与虚拟 CPU 一样多的并行工作线程,我建议使用:
nproc | xargs -I % make -j%
它可以编写为独立命令或RUN
内部指令Dockerfile
(因为 Docker 不支持嵌套命令)