如何确定传递给 make -j 选项的最大数量?

tar*_*yte 58 linux cpu make multiprocessor parallelism

我想尽可能快地编译。去搞清楚。并想自动选择-j选项后面的数字。如何以编程方式选择该值,例如在 shell 脚本中?

输出是否nproc等于我可用于编译的线程数?

make -j1 make -j16

Ste*_*itt 65

nproc给出可用的 CPU 内核/线程数,例如在支持双向 SMT 的四核 CPU 上为 8。

您可以make使用该-j选项并行运行的作业数量取决于许多因素:

  • 可用内存量
  • 每个make作业使用的内存量
  • 到何种程度make的作业是I / O-或CPU结合的

make -j$(nproc) 是一个不错的起点,但您通常可以使用更高的值,只要您不耗尽可用内存并开始抖动。

对于真正快速的构建,如果您有足够的内存,我建议使用 a tmpfs,这样大多数作业将受 CPU 限制,并且make -j$(nproc)会尽可能快地工作。

  • 和 `ccache` 用于以后重建,但这是 OT (3认同)
  • @terdon 不。Make 就是解决依赖关系,这意味着作业仍然必须按特定顺序运行。GNU parallel 不关心这个。附带说明一下,决定哪些作业可以安全并行运行,哪些不是一个难题。所有提供并行构建的 make 程序都需要数年时间才能变得可用。 (3认同)
  • 这不是一个很好的答案,但本着以编程方式确定最快的“j”值问题的严格精神,您可以将 j 从 1 循环到某个合理的上限(2x nproc??)并将 make 包装在`time`中称呼。清理结果,泡沫冲洗重复 - 最后排序时间/ j 值。 (2认同)

010*_*101 16

最直接的方法是nproc像这样使用:

make -j`nproc`
Run Code Online (Sandbox Code Playgroud)

该命令nproc将返回您机器上的内核数。通过将其包装在刻度中,该nproc命令将首先执行,返回一个数字,该数字将被传递到make.

您可能有一些轶事经验,执行 core-count + 1 会导致更快的编译时间。这更多地与 I/O 延迟、其他资源延迟和其他资源限制的可用性等因素有关。

要做到这一点nproc+1,试试这个:

make -j$((`nproc`+1))
Run Code Online (Sandbox Code Playgroud)

  • +1,因为脚本使用了 nproc+1,这解释了原因。 (3认同)

Dan*_*scu 8

不幸的是,即使同一构建的不同部分在 j 因子值冲突时也可能是最佳的,这取决于正在构建的内容、方式、当时哪些系统资源是瓶颈、构建机器上正在发生的其他事情、正在发生的事情网络(如果使用分布式构建技术)、构建中涉及的许多缓存系统的状态/位置/性能等。

编译 100 个微小的 C 文件可能比编译一个巨大的 C 文件更快,反之亦然。构建小的高度复杂的代码可能比构建大量的直接/线性代码慢。

甚至构建的上下文也很重要 - 使用针对专用服务器上的构建优化的 j 因子针对独占的、非重叠的构建进行了微调,当开发人员在同一共享服务器上并行构建时使用它可能会产生非常令人失望的结果(每个这样的构建可能需要更多时间比所有这些序列化的总和)或在具有不同硬件配置或虚拟化的服务器上。

还有构建规范的正确性方面。非常复杂的构建可能存在竞争条件,导致间歇性构建失败,其发生率会随着 j 因子的增加或减少而变化很大。

我可以继续。关键是你必须在你的上下文中实际评估你的构建你想要优化 j 因子的。@Jeff Schaller 的评论适用:迭代直到找到最合适的。就我个人而言,我会从 nproc 值开始,仅当向上尝试显示立即降级时,先向上尝试,然后向下尝试。

首先在假定相同的上下文中测量几个相同的构建只是为了了解测量的可变性可能是一个好主意 - 如果太高可能会危及您的整个优化工作(20% 的可变性将完全掩盖 10% 的改进/ j因子搜索中的退化读数)。

最后,恕我直言,这是更好地使用(自适应)jobserver如果支持并提供的,而不是一个固定的Ĵ因素-它始终提供了跨语境的范围更宽更好的构建性能。

  • `make -j` 将产生依赖项允许的尽可能多的工作,就像一个叉子炸弹 (http://superuser.com/questions/927836/how-to-deal-with-a-memory-leaking-fork-bomb-on -linux/927967#927967); 构建将最多花费大部分 CPU 来管理进程而不是运行它们(http://superuser.com/questions/934685/how-to-find-what-is-pegging-cpu-in-linux-kernel/934839 ?noredirect=1#comment1269087_934839) 并且在高度并行的构建中,系统将耗尽内存/交换或 pid #s,构建将失败。 (5认同)