核心思路:1)通过轻工作量的预处理阶段,把矩阵A纵向从上到下分割成一个个的row-slice,划分后每个row-slice中的非零元个数大致相同。每个row-slice由一个CPE单独计算。
2)计算一个row-slice时,读取相应的x时使用动态前向规划技术避免取到无用的x,降低了带宽。
3)对CPE进行划分,同组CPE可以共享所需要的x,可进一步降低带宽。
4)设计了parameter auto-tuning框架(我理解就是测试套件),使得算法更适用于不同的矩阵。
5)运行时采用atomic-operation based work-sharing pool确保负载平衡,这项主要配合1)
下面是详细说明:
1)预处理阶段
MPE确定每个row-slice最多包含多少行、最多有多少个非零元后,对矩阵A进行一次遍历,遍历后的划分出的每个row-slice包含非零元个数大致相同。另外,row-slice中同一行的元素也是分批读取的。
2)如何避免取到无用的x
如上图,很显然x中有两部分是不需要取到内存中的,如何发现这两部分呢?计算的过程中,x是分段被读取到LDM的,只要取x时跳过无用的部分即可。计算时,当前分段非零元列坐标中的最大值jl是可以得到的,那么下一个无用x子区间的起始点就是jl + 1。设置向量row_process,其第i个元素记录当前row-slice中第i行下一个要使用的非零元的列坐标,记为ju。这样一来,一个无用x区间[jl + 1,ju - 1]就确定下来。下次取x的时候,跳过这个区间即可。
3)为共享所需的x,对CPE的划分方式
为了充分利用CG中同一行CPE可以快速交换数据这一特性,CPE进行分组以小组为单位来获取一组CPE都需要的数据。这主要分成2个阶段:DMA阶段和broadcast阶段。以下图为例,4个CPE一组,被取x的分段记为seg,把seg分成4部分,seg-0到seg-3.在DMA阶段,每个CPE都以DMA的方式从主存读取对应小分段。在broadcast阶段,同组CPE按顺序把自己的数据广播给其他CPE,这样就避免了同组CPE的冗余访存,从而降低了同组CPE读取相同数据的带宽。
需要说明的是,同组CPE需要在预处理阶段先算得需要x的下标范围。这里说的下标范围应该是每次进入内存的总区间,仅仅是下标范围,并没有去掉无用的x部分。原文是这样说的:.The union of all the indices of the required x segments by a row-slice set can also be assembled in the preprocess phase, so that the x segments can be collectively accessed by the peers in a group。总觉得这个和3)有些矛盾。.
4)parameter auto-tuning技术
多次实验之后取得最佳参数配置。需要确定的参数有:预处理阶段单个row_slice最多包含行数或非零元个数、计算时同行元素的分割区间大小。同时测试时还会检查参数合法性。
5)atomic-operation based work-sharing pool技术
预处理阶段结束后,所有row_slice形成一个任务队列,设置全局变量row-slice counter做计数器。同组CPE从任务队列取任务时,要使用原子操作对计数器自增,确保每个row-slice只计算一次。
补充:这篇文献没有伪代码,看完以后觉得计算过程不是很清晰。主要问题是对x的读取过程不是很清楚。如果采用了dynamic look-ahead技术的话,肯定是边计算边读取相应x的。但是后面又说要对CPE进行分组,分组后以组为单位读取x再分配,重新提到了预处理阶段,没有说到底在哪一步读取x进LDM。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)