在并行管道中使用空闲内核?

时间:2013-12-03 18:47:03

标签: parallel-processing pipeline

我一直在阅读关于并行管道的this教程,并注意到,虽然吞吐量肯定存在很大差异,但如果压缩阶段也从事读取工作,那么情况就更好了它只是在等待?写入阶段也是如此...我的意思是,为什么不进行第三次压缩然后切换到写入两次,然后让其中一个核心返回压缩而另一个核心包装第三次写入,等等?

如果这很明显,我道歉。我想这是标准做法,被称为某种东西,我只是不确定是什么。他们的任何开销是否涉及切换这样的工作?

我知道这可能是最后一个问题的错误论坛,但GPU可以切换这样的工作,还是可编程着色器/ CUDA内核在编程后几乎不会被单独留下?

编辑:我想我也不明白如何在2个核心/阶段示例中使用相同的6个核心比仅仅给出6个核心中的每个核心更快。当然,有两个核心会做两个,但仍然比顶级场景更快。我会在GPU的情况下更好地理解它,因为某些计算涉及专用硬件,但一般来说,我没有看到它。也许这个例子很弱或者是因为我知道并行处理就在这里。

Parallel Pipeline

2 个答案:

答案 0 :(得分:1)

这绝对是流水线操作的问题,有许多不同的方法可以尝试和减轻它。

使用专用硬件时,通常会调整硬件以尝试平衡每个阶段对典型工作负载所花费的时间。例如,GPU中的固定功能级通常围绕代表性游戏渲染工作负载的样本的需求进行平衡,其中晶体管被分配以尝试并平衡每个阶段所花费的时间。对于像这样的静态平衡,通常会有一些浪费的性能。

可用于软件和硬件以平衡管道的替代方法是将较长的阶段分解为多个较短的步骤。这是CPU指令流水线中的常用策略,但在软件中也很有用。在您的示例中,较长时间运行的压缩步骤可能会分解为多个较短的管道阶段。根据任务的不同,这可能很难或不可能有效地完成。

任务调度系统可用于帮助平衡软件管道中CPU之间的工作负载。在任务调度系统中,您有许多工作线程(通常每个硬件线程一个),任何任务都可以在任何工作线程上运行。您有一个API来设置任务之间的依赖关系,任务调度程序负责调度任务,以便在满足其依赖关系后,在CPU时间可用的任何地方运行。在您的示例中,具有空闲时间运行读取和写入任务的核心可以帮助解决压缩任务,而不是在压缩任务满足其读取任务依赖性时保持空闲状态。

传统的OS线程调度程序可以提供任务调度系统的一些相同的好处。在您的示例中,如果读取线程在其工作队列为空时等待信号量(在将新工作添加到队列时发出信号),则操作系统可以安排压缩线程在这些空闲核心上运行。对于相对长时间运行的流水线阶段(10毫秒),这可以很好地工作,但是对于较短的流水线阶段(子1ms),OS线程调度的开销和线程时间片的长度可能意味着任务调度系统会提供更好的性能

答案 1 :(得分:1)

您的观点有效。该教程缺乏。

如果读取,压缩和写入操作都可以独立完成,那么简单的非流水线情况对于六个内核来说是最快的。另请注意,在六个核心图中,读取和写入从不重叠,因此它们可能是相同的。您只需要四个核心。

但是考虑一种情况,即读取都访问同一个磁盘,因此并行发出太多读取操作会使读取时间变长,因为它们互相干扰。在这种情况下,您可以通过管道读取来获得,因为您可以更快地启动第一个压缩步骤并限制它们 整体表现。