【发布时间】:2016-06-09 19:48:37
【问题描述】:
我知道要让make 成为多线程,我使用命令make --jobs=X,其中X 通常等于核心数(或两倍或其他)。
我正在调试一个 makefile - 实际上由许多 makefile 组成 - 以使用 --jobs=X 选项。下面是一个为什么它目前没有的例子:
T1:
mkdir D1
output_makefile.bat > ./D1/makefile
T2:
cd D1
make
使用--jobs=X 执行此操作将导致竞争条件,因为T1 未指定为T2 的依赖项,最终T2 将在T1 之前构建;我需要修复的大多数错误都属于这种类型。
如果--jobs=X 中的X 大于逻辑或物理的数量?核心,同时执行的作业数量将被限制为逻辑或物理数量?核心。
我的机器有 4 个物理核心/8 个逻辑核心,但运行我们构建的构建机器将有多达 64 个核心。
所以我担心,仅仅因为我的 makefile (a) 正确构建最终输出 (b) 在我的机器上使用 --jobs=4 运行而没有错误并不意味着它会在 --jobs=64 上正确运行并且没有错误一台 64 核的机器。
是否有工具可以模拟make 在内核数多于物理机的环境中执行?
如何创建一个 64 核的虚拟机并在我的 4 核机器上运行它;这甚至是 VMPlayer 允许的吗?
更新 1
我意识到我对 make 的理解是错误的:job slots make 创建的数量等于 --jobs=N 参数,而不是我的 PC 拥有的内核或线程数。
然而,这本身并不一定意味着make 也将执行这些作业并行即使我的核心比作业少使用任务-切换。
我需要确认所有作业都是并行执行的,而不是仅仅“排队”并等待主动执行的作业完成。
所以我创建了一个包含 16 个目标的 makefile - 超过了我拥有的线程或内核的数量 - 每个配方只是 echos 目标名称的可配置次数。
make.mk
all: 1 2 3 4 ... 14 15 16
<target X>:
@loop_output.bat $@
loop_output.bat
@FOR /L %%G IN (1,1,2048) DO @echo (%1-%%G)
输出将类似于
(16-1) <-- Job 16
(6-1400)
(12-334)
(1-1616) <-- Job 1
(4-1661)
(15-113)
(11-632)
(2-1557)
(10-485)
(7-1234)
(5-1530)
格式为Job#X-Echo#Y。我看到(1-1616) after (16-1) 的事实意味着make 确实在执行目标16 和目标1。
另一种选择是 make 完成作业(1-#of cores/threads)然后 然后 占用另一块等于 #num cores/threads 的作业,但事实并非如此。 p>
【问题讨论】:
-
为什么不使用 Make 的自然依赖处理能力来防止竞争条件?
-
“同时执行的作业数量将被限制为?逻辑或物理?核心的数量。”没有这样的保证,你只是在你的机器上试过
-j64/--jobs=64吗? -
@Beta
make只能处理您告诉它的依赖项。在上面的示例中,它没有检查配方并推断T2依赖于T1。这种推断是由 Electric-Cloud 的 Huddle 提供的,我正在使用它,它很棒。但它不是免费的。 -
您可以检查配方,推断依赖关系并添加先决条件。这不就是“调试makefile”的意思吗?
-
@Beta 然后我必须以某种方式同时执行任意数量的作业来严格测试它,即不管我拥有多少核心。这是我的问题。
标签: multithreading makefile gnu-make