Page 328 - 《软件学报》2021年第9期
P. 328
2952 Journal of Software 软件学报 Vol.32, No.9, September 2021
流程如下:每个节点的 0 号主核负责通信,将通信完成指示变量定义为节点共享变量,节点内所有主核同时
可见.那么节点内的主核间可通过节点共享变量进行同步,无需显式同步.此时,每个核组的 0 号从核等待通信完
成指示变量的变化.当该变量加 1 后,说明主核已完成通信,接收到其他节点在 t 时刻的状态信息.0 号从核此时
需要将此状态同步给所在核组的其余 63 个从核.同一核组的从核间同步速度较快,无需访存.每个核组的从核
完成组内同步后,从核开始并行加速计算.核组内所有从核完成计算后,该核组内的 64 个从核经过一次从核同
步,以保证 64 个从核状态统一.从核同步后,每个核组的 0 号从核将计算完成的节点共享变量加 1.该共享变量对
所有核组的主核同时可见.所有从核加速计算的同时,0 号通信主核等待 4 个 0 号从核计算完成的节点共享变量
的变化.当 0 号主核检测到 4 个 0 号从核均将计算完成指示变量加 1 后,0 号主核开始与其他节点进行通信.至
此,完成一个完整的迭代步.主从核的代码实现参见图 12、图 13 的虚代码所示.
//从核代码
//主核代码 1: for iter=0 to NITERS do
1: for (NODE_ID==0) //0号主核 2: ral=r+1
2: for iter=0 to NITERS do 3: if (ARRAY_ID==0)
3: ral=r+1 4: wait(waitcomm,r)
4: for v=0 to 4 do 5: end if
5: wait(waitcomp,ral) //等待从核计算完成 6: sync(ARRAY) //从核同步
6: end for 7: computing(⋅) //从核计算
7: exchange(⋅) //通信 8: sync(ARRAY) //从核同步
8: waitcomm=ral //修改通信完成变量 9: if (ARRAY_ID==0) //0号从核
9: end if 10: waitcomp[NODE_ID]=ral //修改计算完成变量
10: end for 11: end if
12: end for
Fig.12 Code on MPE for shared memory waiting Fig.13 Code on CPEs for shared memory waiting
图 12 共享内存等待算法的主核代码 图 13 共享内存等待算法的从核代码
神威异构体系结构下,单核组通信的模式需利用核间同步,以同步通信数据.SW26010 芯片的硬件结构决定
了主从核之间同步需要访问片外存储器,申威处理器较长的访存延迟导致该同步模式效率较低,本文采用共享
内存等待的方式规避访存延迟.共享内存等待方式的优势是:核组间无需显式同步,只需要设置共享内存等待变
量;该变量对节点内所有主核同时可见,只需要检测共享内存指示变量的变化来实现不同核组间的隐式同步,避
免了核组同步时的访存操作,规避了申威处理器较长的访存时延.
2.2 改变计算模式,减少核间等待,优化通信延迟
2.2.1 基本的并行模式
共价键分子的原子间相互作用势不仅取决于原子间的距离,与原子间的成键方向有密切关系,因此需要考
虑周围原子的影响.硅原子之间的多体作用模型采用 Tersoff 势函数 [14] ,计算涉及两个以上的原子.计算原子 i 受
到它的邻居 j 的作用力时,需要考虑 i 的其他 3 个邻居此时对 i 的影响.见图 14:由 Tersoff 势函数可得到邻居 j
对 i 的作用力 func1,力是相互作用力,原子 j 也受到了一个大小相等方向相反的作用力−func1,并且需要加到 j
原子上 [17] .在神威上是多线程计算,j 粒子同时在由另外一个线程计算 j 粒子与它的邻居粒子之间的受力.这个方
向相反的作用力−func1 在同一时刻不能同时加到 j 粒子身上.基本算法是:需要存储本线程所计算的对应原子受
到其所有邻居原子的全部作用力,通过同步,传递给对应原子所在线程.所有邻居原子线程的受力计算结束后,
接收消息,将原子受到的邻居粒子的反作用力叠加起来,保证所有原子作用力的计算是完整的、准确的.
对每个原子 i 而言,以计算它的邻居粒子 j=0 对它的作用力 func1 为例,说明受力计算的过程.首先,计算邻居
粒子 j 对 i 的作用力时,需要考虑 i 粒子其余 3 个邻居粒子 k 0 ,k 1 ,k 2 此时对 i 的影响.func1 是 i 和 j 之间大小相等、
方向相反的相互作用力,即 i 粒子对 j 粒子的反作用力−func1,需同时累加到 j 粒子上.若为并行程序,此时 j 粒子
正在由其他线程计算 j 粒子与它的邻居粒子之间的受力.不能同时把−func1 累加到 j 粒子上,需要交互粒子信息.
最后,其他的 3 个邻居粒子也受到了反作用力−func2,同样需要在 3 个粒子的受力上减去.受力计算结束后,算法
采用蛙跳格式更新位移.