如何使用源代码测量每个节点的MPI基准?

时间:2016-08-03 12:52:34

标签: c mpi openmp benchmarking memory-bandwidth

我想知道如何测量内存带宽(流基准)PER NODE。我所拥有的这个程序,仅在一个节点上测量它,进程和线程的数量将采用如下:

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-batch脚本来完成它。 我可以使用process-ID指定每个节点的第一个核心但是每次如何在整个节点上运行测量(包括任意数量的核心)?

任何建议都会受到赞赏。

1 个答案:

答案 0 :(得分:1)

自从我使用MPI以来已经有一段时间了,所以我并没有真正回答"如何编写代码"题。我更关注事物的基准测试方法,所以你希望能够设计它来实际测量有用的东西。基准测试很难;它很容易得到一个数字,很难得到一个有意义的数字来衡量你想要衡量的数字。

您可以只查询获得的节点,而不是指定您获得的节点。 (即检测MPI作业的多个进程在同一物理主机上结束,争夺内存带宽的情况。)

您还可以随机化每个节点上运行的线程数,或者其他内容,以查看带宽如何随着执行memcpy,memset或者只读(如减少或memcmp)的线程数而缩放。

在最近的英特尔Xeons上,每台机器的一个线程几乎没有接近饱和的内存带宽,除了可能与台式机CPU类似的低核心数CPU。 (然后,只有当您的代码编译为高效的矢量化asm时)。 L3 /内存延迟对于单个内核的有限内存并行性来说太高而无法满足吞吐量。 (请参阅Why is Skylake so much better than Broadwell-E for single-threaded memory throughput?中的Enhanced REP MOVSB for memcpy和"延迟限制平台"。

运行带宽瓶颈的代码(如STREAMS基准测试)需要4到8个线程才能使多核Xeon的内存带宽饱和。除非您使用非常小的数组进行测试,否则更多的线程将具有相同的总数,因此私有的每核L2缓存发挥作用。 (现代英特尔CPU上的256kB,而每个核心L3的大型共享~2MB)。更新:Skylake-AVX512上每个核心私有L2 1个MiB。

对于双插槽节点,NUMA是一个因素。如果您的线程最终使用的内存全部映射到一个套接字上的物理内存控制器,而另一个套接字的内存控制器处于空闲状态,那么您只能看到机器带宽的一半。这可能是测试内核的NUMA感知物理内存分配对您的实际工作负载做得很好的一种好方法。 (如果您的带宽微基准测试与实际工作负载类似)

请记住,内存带宽是节点上所有内核的共享资源,因此,为了获得可重复的结果,您可能希望避免与其他负载竞争。即使是占用内存较少的东西也可能会占用大量带宽,如果它的工作集不适合私有的每核L2缓存,那么不要以为其他工作不会争夺内存带宽只是因为它只使用了几百MB。