【发布时间】:2026-01-18 14:10:01
【问题描述】:
假设我有 M 个独立的工作,每个工作有 N 个步骤。作业彼此独立,但每个作业的步骤应该是连续的。换句话说,J(i,j) 应该在 J(i,j-1) 完成之后才开始(i 表示作业索引,j 表示步骤)。这与建造一堵宽 M 高 N 块的墙是同构的。
每个作业块只能执行一次。使用一个CPU做一个block的工作(也是同一个顺序)所花费的时间对于不同的block来说是不同的,并且是事先不知道的。
使用 MPI 执行此操作的简单方法是将工作块分配给处理器,并等到它们全部完成它们的块后再进行下一次分配。这样我们可以确保执行优先级,但会有很多等待时间。
有没有更有效的方法来做到这一点?我的意思是当一个处理器完成它的工作时,使用某种环境变量或共享内存,它可以决定它接下来应该执行哪个工作块,而无需等待其他处理器完成它们的工作并使用通信做出集体决定。
【问题讨论】:
-
这听起来类似于 h.265(视频编解码器)对 Wavefront Parallel Processing 所做的事情,其中每个视频块都依赖于其上方和左侧的块。将依赖项限制为该模式允许比任意依赖项更多的并行性。您可能想看看该系统是如何设计为您的想法的,除了您显然在工作之间没有任何依赖关系,但您仍然希望它们相互等待。
-
为什么所有 M 个工作都处于相似的进度阶段很重要?如果 M 中的某些作业在其他作业完成之前才开始(即将所有 N 个步骤放入单个作业调度器作业中),是否可以?或者这会导致您只剩下几个串行作业,因此您无法利用所有 CPU?根据每个步骤的大小,缓存可能很重要,因此在同一台机器(甚至同一集群节点的相同 CPU)上对相同数据执行多个步骤可能很重要。
-
另一种简单的方法可能是将一个 CPU(例如 p0)分配为调度器/仲裁器,这样每个 CPU 都需要在空闲时进行注册。 p0 可以自适应地对作业/块进行排序并将它们分配给 CPU。这将引入一些通信开销的想法。类似的事情可以用共享内存来做,谁有空,谁就拿下一个块,而创建“订单”以方便挑选的任务是共享的
-
@peterCordes 工作是否处于相似阶段并不重要,如果 M = integer * num_cpu,那会起作用(即使没有优化),
-
@makadev 共享内存的解决方案很有趣,如果我可以有一些共享变量,它们会在所有处理器中立即更新(如果它们被特定的 cpu 更改)我认为有可能找到一个好的解决方案。不确定英特尔 MPI 是否可能有这样的变量。