我想知道如何测量每个节点的内存带宽(流基准)。我的这个程序,只在一个节点上测量它,进程和线程的数量如下:
MPI_Comm_size(MPI_COMM_WORLD, &numranks);
MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
omp_set_dynamic(0);
omp_set_num_threads(4);
#pragma omp parallel
{
}
它实际上是mpi和openmp的混合体。是否有任何方法可以指定节点并对每个节点进行测量?(假设我有4个节点)我想使用源代码而不是slurm批处理脚本。我可以使用进程ID指定每个节点的第一个核心,但它每次如何在整个节点上运行测量(包括任何数量的核心)?
任何建议都将不胜感激。
我已经有一段时间没有使用MPI了,所以我并没有真正回答"如何编写代码"的问题。我更关注的是基准方法论方面的东西,所以你希望可以设计它来实际衡量一些有用的东西。制定基准很难;很容易得到一个数字,很难得到一个有意义的数字来衡量你想要衡量的东西。
您可以查询得到的节点,而不是指定得到的节点。(即,检测MPI作业的多个进程最终在同一物理主机上竞争内存带宽的情况。)
您还可以随机化在每个节点上运行的线程数,或者其他什么,以查看带宽如何随着执行memcpy、memset或reduction或memcmp等只读操作的线程数而扩展。
在最近的Intel Xeons上,每台机器一个线程不会接近饱和的内存带宽,除了类似于台式CPU的低核CPU。(然后只有当您的代码编译为高效的矢量化asm时)。L3/内存延迟太高,单核的有限内存并行性无法使吞吐量饱和。(请参阅为什么Skylake在单线程内存吞吐量方面比BroadwellE好得多?以及增强型REP MOVSB中的"延迟绑定平台"在内存吞吐量方面。)
运行带宽瓶颈代码(如STREAMS基准测试)可能需要4到8个线程才能使多核Xeon的内存带宽饱和。更多的线程将具有大致相同的总数,除非您使用非常小的阵列进行测试,这样每个核心的专用二级缓存就会发挥作用。(在现代英特尔CPU上为256kB,而在大型共享型L3上为约2MB)。更新:Skylake-VX512上每个核心1 MiB的专用L2。
对于双套接字节点,NUMA是一个因素。如果你的线程最终使用的内存都映射到一个套接字上的物理内存控制器,而另一个套接字的内存控制器处于空闲状态,那么你只能看到机器带宽的一半。这可能是测试内核的NUMA感知物理内存分配是否能很好地满足实际工作负载的好方法。(如果您的带宽微基准与实际工作负载非常相似)
请记住,内存带宽是节点上所有核心的共享资源,因此为了获得可重复的结果,您需要避免与其他负载竞争。即使是内存占用较小的作业,如果其工作集不适合专用的每核二级缓存,也会占用大量带宽,所以不要因为另一个作业只使用几百MB就认为它不会竞争内存带宽。