我正在完成一种基于分布式桶排序的"Terasort Lite“礼拜堂计划的实现,并且我注意到访问块分布式数组似乎存在着严重的性能瓶颈。一个粗略的基准测试显示,Chapel需要花费大约7秒的时间来完成5个地区的3.5MB的整类工作,而最初的MPI+C程序则需要8.2ms左右的5个进程来完成。我的本地机器有16个核心,所以我不需要过订阅MPI才能让5个进程工作。
要排序的数据被加载到跨每个区域设置的块分布数组中,这样每个区域设置都具有未排序记录的偶数(和连续)共享。在MPI+C桶排序中,每个进程将在内存中保存其记录,并对这些本地记录进行排序。为此,我编写了一个基于extreme实现(基于extreme实现)的具有地区意识的qsort实现,这就是我看到的极限性能瓶颈。整个桶排序过程引用一个块分布式数组,并使用本地子域:qsort (来自coforall块和on loc do子句)调用coforall。
我的主要问题是Chapel如何在分布式数组上保持一致性,以及跨区域的任何类型的一致性行为是否会抹杀我的性能。我已经检查过了,每个区域设置的qsort调用都只访问其本地子域中的数组索引;我预计这意味着不需要通信,因为每个区域设置只访问它所拥有的部分域。这是一个合理的期望,还是同时访问分布式数组的私有部分会导致通信开销?
在上下文中,我使用UDP GASNET通信基板在本地运行一台物理机器,文档注意到这并不能提供良好的性能。尽管如此,我确实计划使用InfiniBand将代码移动到集群中,因此我仍然想知道是否应该以不同的方式来处理这个问题,以获得更好的性能。如果有其他信息可以帮助回答这个问题,请告诉我。谢谢!
发布于 2022-07-14 12:38:27
谢谢你的问题。我可以在这里回答一些问题。
首先,我想指出Chapel中的一些其他分布式排序实现:
一般来说,我希望基数排序在局部问题上优于快速排序,除非它们非常小。
现在请回答你们的问题:
我的主要问题是Chapel如何在分布式数组上保持一致性,以及跨区域的任何类型的一致性行为是否会抹杀我的性能。
默认情况下,远程数据有一个缓存。编译时可以用--no-cache-remote禁用它,但我怀疑这不是问题所在。特别是,它主要在某种类型的内存围栏上执行任何一致性活动(包括语句、任务结束、使用同步/原子变量)。但是,你可以关掉它,看看它是否改变了一切。
分布式阵列和域目前使用的是一种迫切的私有化策略。这意味着,一旦创建了这些元素,数据结构的某些元素就会在所有区域设置中被复制。由于这涉及所有区域设置,因此在运行多区域设置时可能会导致性能问题。
您可以检查内核中是否与CommDiagnostics模块或区块通信。CommDiagnostics模块将允许您计数或跟踪通信事件,而如果尝试在local模块内进行通信,则local块将停止程序。
另一种可能是编译器没有生成通信,但是运行速度较慢,因为当数据可能是远程的时候,它很难进行优化。问题在于,使用CHPL_COMM=none编译时所获得的性能要比使用gasnet和UDP运行1 locale时要快得多。(您也可以使用--local和--no-local标志进行比较)。一些可能有助于实现这一目标的方法:
records[records.localSubdomain()]而不是records.localSlice(records.localSubdomain()),但这使用了一个无文档化的特性。不过,我不知道为什么它是无证的。local块也可以解决这个问题,但是请注意,我们通常尝试以其他方式解决这个问题,因为local块是一个很大的锤子。切片的开销比我们想要的要大。参见例如https://github.com/chapel-lang/chapel/issues/13317。正如我所说,也可能有私有化成本(我不记得当前的切分和私有化的情况是什么,直接)。根据我的经验,对于本地排序代码,最好将起始参数和结束参数作为In传递,或者传递范围;但是切片以获得数组的局部部分在分布式设置中肯定更重要。
最后,您提到在运行超额订阅时,您正在尝试分析性能。如果您还没有看到它,请查看有关推荐设置的超额订阅的文档。。
https://stackoverflow.com/questions/72973702
复制相似问题