如何在多核Linux机器上使用GNU make --max-load?

Dan*_*iel 12 multicore uptime gnu-make

从GNU make的文档:http://www.gnu.org/software/make/manual/make.html#Parallel

当系统负载很重时,您可能希望运行的作业少于轻载时的作业.您可以使用'-l'选项告诉make根据平均负载限制一次运行的作业数.'-l'或'--max-load'选项后跟一个浮点数.例如,

 -l 2.5
Run Code Online (Sandbox Code Playgroud)

如果负载平均值高于2.5,则不会让make启动多个作业.没有跟随号码的'-l'选项会删除加载限制,前提是前一个'-l'选项.

更准确地说,当make启动一项工作,并且它已经至少运行了一个工作时,它会检查当前的平均负载; 如果它不低于'-l'给出的限制,则等待直到负载平均值低于该限制,或直到所有其他作业完成.

从Linux手册页获取正常运行时间:http://www.unix.com/man-page/Linux/1/uptime/

系统负载平均值是处于可运行或不可中断状态的平均进程数.处于可运行状态的进程要么使用CPU,要么等待使用CPU.处于不可中断状态的进程正在等待某些I/O访问,例如等待磁盘.平均值是在三个时间间隔内取得的.对于系统中的CPU数量,负载平均值没有标准化,因此平均负载为1意味着单个CPU系统一直在加载,而在4 CPU系统上,这意味着它在75%的时间内处于空闲状态.

我有一个并行的makefile,我想做一个显而易见的事情:make make继续添加进程,直到我获得完整的CPU使用率,但我不会引起颠簸.

今天的许多(所有?)机器都是多核的,因此这意味着负载平均值不是应该检查的数量,因为需要针对核心数调整该数量.

这是否意味着GNU make 的--max-load(又名-l)标志现在没用了?在多核计算机上运行并行makefile的人在做什么?

Bri*_*erg 7

我的简短回答:--max-load如果您愿意投入时间来充分利用它,那将非常有用.根据目前的实施情况,没有简单的公式可以选择好的价值,也不需要预制工具来发现它们.


我维护的构建相当大.在我开始维护它之前,构建是6个小时.与-j64上一个虚拟盘,现在它完成在5分钟(30上的与NFS安装-j12).我的目标是找到合理的上限-j-l允许我们的开发人员快速构建,但不会使服务器(构建服务器或NFS服务器)无法用于其他所有人.

首先:

  • 如果您选择一个合理的 -jN值(在您的机器上)并找到合理的平均负载上限(在您的机器上),它们可以很好地协同工作以保持平衡.
  • 如果您使用非常大的-jN值(或未指定;例如,-j没有数字)并限制平均负载,gmake将:
    • 继续产生进程(gmake 3.81添加了一个限制机制,但这只能帮助缓解一点问题),直到达到最大作业数或者直到负载平均值超过阈值
    • 当负载平均值超过您的阈值时:
      • 在所有子流程完成之前什么都不做
      • 一次产生一份工作
    • 再做一遍

至少在Linux上(可能还有其他*nix变体),负载平均值是一个指数移动平均值(UNIX负载平均值重估,Neil J. Gunther),表示等待CPU时间的平均进程数(可能由过多进程引起) ,等待IO,页面错误等).由于它是指数移动平均线,因此它的加权使得较新的样本对当前值的影响比旧样本更强.

如果你可以确定正确的最大负荷和平行工作数量的良好"最佳位置"(通过有根据的猜测和经验测试的组合),假设你有一个长期运行的建立:你的1分钟平均将达到平衡点(不会波动太多).但是,如果您的-jN数字对于给定的最大平均负载而言太高,则会有相当大的波动.

找到最佳位置基本上等于找到微分方程的最佳参数.由于它将受初始条件的影响,因此重点是找到使系统保持平衡的参数,而不是提出"目标"负载平均值."平衡"是指:1m负载平均值不会波动很大.

假设你没有受到gmake限制的瓶颈:当你找到一个-jN -lM能够提供最短构建时间的组合时:这种组合会将你的机器推向极限.如果机器需要用于其他目的......

编译

...当你完成优化时,你可能想稍微缩小一点.

不考虑负载平均值,我在构建时间中看到的改进增加-jN似乎是[大致]对数.也就是说,我看到了区别较大-j8-j12较之间-j12-j16.

事情在我-j48-j64它之间的某些地方达到了顶峰(在Solaris机器上它是关于的-j56),因为最初的gmake进程是单线程的; 在某些时候,线程无法比完成更快地开始新的工作.

我的测试是在:

  • 非递归构建
    • 递归构建可能会看到不同的结果; 他们不会遇到我所做的瓶颈-j64
    • 我已经尽力减少配方中的make-isms(变量扩展,宏等)的数量,因为配方解析发生在产生并行作业的同一个线程中.配方越复杂,它在解析器中花费的时间就越多,而不是产生/收割作业.例如:
      • $(shell ...)配方中没有使用宏; 这些是在第一次解析过程中运行并缓存的
      • 分配大多数变量:=以避免递归扩展
  • Solaris 10/sparc
    • 256个核心
    • 没有虚拟化/逻辑域
    • 构建在ramdisk上运行
  • x86_64 linux
    • 32核(4x超线程)
    • 没有虚拟化
    • 构建在快速的本地驱动器上运行


Fre*_*ord 1

如今许多(全部?)机器都是多核的,因此这意味着平均负载不是 make 应该检查的数字,因为该数字需要根据核心数量进行调整。

这是否意味着 GNU make 的 --max-load (又名 -l)标志现在没用了?

不。想象一下对磁盘 I/O 要求很高的作业。如果您启动的作业数量与 CPU 数量一样多,您仍然无法很好地利用 CPU。

就我个人而言,我只是使用 -j 因为到目前为止它对我来说已经足够好了。