OpenSHMEM在Adapteva Epiphany协处理器上的实现及相关特性评估
1. OpenSHMEM在Epiphany架构下的内存管理
在Epiphany架构中,由于没有虚拟地址抽象,sbrk更适合控制每个处理元素从SHMEM数据堆分配的内存量。这里有一个本地基内存跟踪指针,它存储当前的空闲内存基地址,并在每次分配时递增。内存管理例程基于这些调用构建,但需遵循以下规则:
1. 如果进行后续分配,shmem free必须按分配的相反顺序调用。
2. shmem realloc只能用于最后一次(重新)分配的指针。
3. shmem align对齐必须是大于8的2的幂(默认值为8)。
调用shmem free会将本地基内存跟踪指针移动到函数参数中的地址,因此如果要释放所有内存,大多数例程只需为一系列分配的第一个缓冲区调用一次。虽然shmem realloc例程可以设计为将旧缓冲区的内容复制到新缓冲区,但这会浪费原始分配中的内存空间。未来使用COPRTHR 2的开发可能会通过将COPRTHR主机端内存管理导出到协处理器线程来解决这些不足。
2. 远程内存访问例程
2.1 高性能内存复制
在Epiphany上,进程间内存复制看似简单,用C代码的简单循环遍历递增的源和目标数组即可实现。但像许多优化的memcpy例程一样,高性能复制并不简单。eLib库中似乎没有高性能的处理器间内存复制例程,因此经过大量手工汇编调优后,编写了一种优化的put方法。该方法利用“零开销”硬件循环以及四路展开交错双字加载和(远程)存储。考虑到Epiphany架构要求加载和存储操作的内存必须与数据大小对齐,还包含了对未对齐内存边缘情况的特殊处理。假设采用快速路径,核心每个时钟周期可传输一个双字(8字节),但由于8字节加载操作需要额外一个周期,实际峰值网络复制速度为每两个时钟周期8字节。对于600 MHz的时钟速率,峰值连续网络传输速度可达2.4 GB/s。固定NoC和核心时钟可确保应用程序通信性能随芯片时钟速度扩展。同样的优化内存复制子例程也用于get操作,但在Epiphany架构上,远程读操作性能永远不如远程写操作,因此通常应避免使用远程读操作。远程直接读操作比等效的远程直接写操作慢,因为读请求必须先通过网络到达接收核心的网络接口,然后数据再通过网络返回请求核心。而远程直接写操作可以直接发出存储指令而无需响应,读操作会使请求核心停滞,直到加载指令将数据返回到寄存器。发出多个请求对缓解此性能问题作用不大,优化后的shmem put吞吐量大约比shmem get高一个数量级。
为解决连续远程读操作的性能差异问题,配置了处理器间中断,由接收核心发出信号,从而执行等效的快速写操作。接收核心在处理器间中断服务程序(ISR)完成后会收到继续执行的信号。这是一个实验性特性,需要在编译时使用SHMEM USE IPI GET启用。该方法对大传输量有最大的性能影响,对于大于64字节的缓冲区有一个转折点,较小的传输直接读取,较大的传输使用处理器间中断。
2.2 非阻塞远程内存访问例程
非阻塞远程内存访问例程(shmem put nbi和shmem get nbi)利用片上DMA引擎。每个处理器节点的DMA引擎有两个独立的DMA通道,可同时执行两个非阻塞传输。每个通道有独立的源和目标地址配置,支持具有灵活步长的2D DMA操作,这可能支持对OpenSHMEM 1.3标准的非阻塞跨步远程内存访问例程的扩展。
对于大的非阻塞传输,将传输拆分为两部分并调用两个非阻塞传输可能会提高应用程序性能,但性能提升通常不明显,甚至可能更差。由于Epiphany - III的硬件缺陷,DMA引擎的带宽被限制在每时钟8字节峰值带宽的一半以下,即4.8 GB/s。如果在未来芯片中完全启用,DMA引擎可用于阻塞远程内存访问例程,而不是远程加载/存储指令。一般来说,使用阻塞传输可能更快,因为DMA引擎的设置开销相对较高,并且并发计算和DMA引擎访问之间经常存在存储体冲突,阻碍了通信和计算的完全重叠。阻塞操作shmem quiet会在DMA状态寄存器上自旋等待,也可以使用DMA ISR来继续shmem quiet操作,但不清楚这样是否能提高性能。
2.3 原子内存操作
Epiphany - III的指令集架构不支持原子指令,但用于远程锁的TESTSET指令可在软件中定义其他原子操作。按照当前代码设计,如果OpenSHMEM规范未来定义了其他原子操作,只需一行代码即可扩展。在核心层面,获取和设置操作的内存访问在单个时钟周期内完成,因此隐式具有原子性。获取操作仍需通过网络到达远程核心并返回结果。每种数据类型的特化根据规范在远程核心上使用不同的锁。32位整数原子例程的性能结果展示了其相关性能。
2.4 集体例程
2.4.1 多核心屏障
多核心屏障对许多并行应用程序的性能至关重要。Epiphany - III包含对完全集体屏障的硬件支持,通过WAND指令和相应的ISR实现。此硬件支持作为OpenSHMEM库中的实验性特性,需要在编译时指定SHMEM USE WAND BARRIER启用。经过多种屏障算法的实现,发现传播屏障是性能最高的软件屏障方法,但不确定该算法在核心数量更多的芯片设计中是否仍能保持最高性能,可能需要替代的树算法。eSDK中的eLib接口使用基于计数器的集体屏障,所需内存随核心数量线性增加,而传播屏障需要8 · log2(N)字节的内存(N为屏障内处理元素的数量)。使用此同步数组可减少屏障每个阶段通过锁进行信号传递的需求。集体eLib屏障完成时间为2.0 µs,WAND屏障为0.1 µs。传播屏障的延迟随核心数量对数增加,超过八个核心时约为0.23 µs。
2.4.2 广播
在Epiphany应用程序开发中,广播很重要,因为它可以减少对公共内存的片外内存访问复制。通过算法方式将片外数据一次性检索并分发给其他处理元素,比每个处理元素单独获取相同的片外数据更快。数据通过逻辑网络树进行分发,先移动最远的数据以防止后续阶段增加片上网络拥塞。广播例程使用与连续数据传输相同的高性能内存复制子例程,有效核心带宽接近该算法的理论峰值性能,约为2.4/log2(N) GB/s。
2.4.3 数据拼接与规约
shmem collect和shmem fcollect例程分别使用环形和递归加倍算法来拼接多个处理元素的数据块,每个例程都使用优化的连续内存复制例程,这些例程可能还有改进空间。shmem TYPE OP to all规约例程对许多多核应用程序很重要,根据处理元素的数量使用不同的算法,非2的幂数量的处理元素使用环形算法,2的幂数量的处理元素使用传播算法。对称工作数组用于临时存储,对称同步数组用于多核锁和信号传递。shmem int sum to all的性能展示了规约操作的相关性能,规约操作中,能适应对称工作数组的操作延迟会有所改善。
2.4.4 全对全数据交换
shmem alltoall连续全对全数据交换例程的性能显示,与其他集体操作相比,该例程的开销延迟相对较高。
2.5 分布式锁定例程
分布式锁定例程(shmem set lock和shmem test lock)可由原子TESTSET指令轻松支持,实际锁地址在实现中定义在第一个处理元素上。这些锁定机制也是多处理元素原子操作的基础,shmem clear lock例程只是简单的远程写操作以释放锁。虽然此方案在Epiphany - III的16个处理元素上效果良好,但在核心数量大幅增加时,性能瓶颈可能会成为问题,应用程序开发人员应避免使用这些全局锁。
以下是相关性能对比表格:
| 操作类型 | 性能描述 |
| ---- | ---- |
| 优化的shmem put | 吞吐量约比shmem get高一个数量级 |
| 集体eLib屏障 | 完成时间2.0 µs |
| WAND屏障 | 完成时间0.1 µs |
| 传播屏障(超过八个核心) | 延迟约0.23 µs |
下面是一个简单的mermaid流程图,展示远程内存访问的基本流程:
graph TD;
A[发起请求] --> B{读或写操作};
B -- 写操作 --> C[直接存储];
B -- 读操作 --> D[请求通过网络到接收核心];
D --> E[数据通过网络返回请求核心];
3. 嵌入式架构的未来工作与扩展探讨
3.1 开源软件发布计划
计划通过美国陆军研究实验室的GitHub账户将ARL OpenSHMEM for Epiphany以及本文中使用的性能评估代码和基准测试作为开源软件发布,以获取Parallella社区的反馈并进行进一步开发。
3.2 架构更新与功能扩展
未来Epiphany架构可能会更新,为许多现有的OpenSHMEM例程提供更多硬件支持。目前提出的许多OpenSHMEM扩展和更新应该是可以实现的。例如,如前文所述,现有的DMA引擎可以支持非阻塞跨步远程内存访问例程。然而,有些扩展对于该架构并不适用,比如Epiphany不是多线程架构,虽然可以通过软件实现多线程,但这并非提高性能的理想机制。OpenSHMEM标准应保持足够轻量级,以处理低级操作,而不依赖特定的架构特性。
3.3 内存管理挑战与改进方向
对于Epiphany架构和其他嵌入式架构来说,OpenSHMEM标准中最具挑战性的部分之一是内存管理例程。对于某些平台,使用预分配的对称堆进行内存分配是有意义的。在Epiphany本地核心中,由于可用内存是从对称堆中线性分配的,物理地址和分配例程返回的内存地址之间没有内存虚拟化。可用核心空间的限制使得引入类似Linux的虚拟内存抽象模型变得困难。由于OpenSHMEM是一个低级接口,并且应用程序开发人员已经习惯了显式管理内存,因此为嵌入式架构改进内存管理接口(如前面讨论的那些)可能是有意义的。
以下是一个关于OpenSHMEM在Epiphany架构上的功能与挑战的表格:
| 功能/挑战 | 描述 |
| ---- | ---- |
| 内存管理 | 无虚拟地址抽象,需遵循特定分配规则,未来或改进 |
| 远程内存访问 | 写操作性能优于读操作,有实验性特性提升读性能 |
| 非阻塞操作 | 利用DMA引擎,但有硬件限制和性能问题 |
| 原子操作 | 软件实现原子性,可扩展 |
| 集体操作 | 多种算法实现不同集体操作,性能有差异 |
| 分布式锁定 | 核心数量增加可能有性能瓶颈 |
下面的mermaid流程图展示了内存分配与释放的流程:
graph TD;
A[开始分配] --> B[调用内存分配例程];
B --> C[更新本地基内存跟踪指针];
C --> D[完成分配];
D --> E{是否释放内存};
E -- 是 --> F[按规则调用shmem free];
F --> G[移动本地基内存跟踪指针];
G --> H[完成释放];
E -- 否 --> I[继续其他操作];
4. 总结
OpenSHMEM为Epiphany架构提供了一种有效且实用的编程模型。仅包含头文件的实现方式使编译器能够对程序大小和应用程序性能进行优化,这是使用标准预编译库难以实现的。尽管OpenSHMEM接口增加了软件抽象层,但与当前的eLib库相比,仍展示了更好的性能和许多有用的特性。ARL OpenSHMEM for Epiphany在接近硬件理论网络限制的同时实现了高性能执行,并且许多OpenSHMEM例程具有低延迟操作的特点。
综上所述,OpenSHMEM在Epiphany架构上展现出了巨大的潜力,通过不断的改进和优化,有望在嵌入式架构的高性能计算领域发挥更重要的作用。开发人员在使用过程中,应根据具体的应用场景和需求,合理选择和使用各种OpenSHMEM例程,以充分发挥其性能优势。同时,对于未来可能的架构更新和标准扩展,也应保持关注,以便及时调整和优化应用程序。
超级会员免费看
20

被折叠的 条评论
为什么被折叠?



