我们知道数据移动带来的延迟是阻碍程序性能的一个非常重要的因素。广义上的数据移动包括几个不同的方面。它包括不同进程间的信息传递(MPI),比如从一维弹簧系统谈多进程并行计算中提到的分散式矩阵矢量乘法。它也包括数据从慢速存储到高速存储的移动,一个例子是如何从Wall/CPU time理解多线程程序的并行效率一文中关注的IO时间,具体来讲是属于发生在主存和硬碟之间的数据移动,以及从2018戈登贝尔奖谈高性能计算提到的数据在不同层次缓存之间的移动。它还包括数据在异质结构中host和target机器之间的移动。
我们为什么如此关注数据移动?因为数据移动受延迟和带宽的限制,在高性能计算程序中往往属于不可并行或者很难并行的部分。那么如何来克服这一难点呢?除了采用更先进的硬体来降低数据移动的延迟和提高数据传输的带宽,我们在本文中讨论一个来自软体层面的方法。
首先定义一个高性能计算程序的抽象模型。如图1所示。我们把程序分成两个部分。其中一个是计算部分,我们假设这一部分是可被完美并行的,即使用n个计算单元,耗时缩短为原来的1/n。另外一个是数据的输入或者输出部分,它抽象了上文中提到的数据移动。为了讨论的方便,我们在模型中独立地看数据的输入和输出,从而得到了一个简单的生产者-消费者模型。这个模型在一定程度涵盖了前文中提到的针对不同层次而实现的并行模型(基于MPI、多线程和异质结构的并行计算)。我们先看两个例子。例如从2018戈登贝尔奖谈高性能计算中提到的深度学习,其中训练数据的输入可以看作图1中的生产者,对模型的训练看作是消费者。再例如传统的动力学模拟,计算部分变成了生产者,对给定时间步的数据输出变成了消费者。