mpi_run 在多核架构上 --bind-to l3 或 --bind-to core

mpi_run on multicore architecture --bind-to l3 or --bind-to core

我是 运行 24c 架构的代码,我想为绑定到 L3 缓存块的每组三个内核使用一个 mpi 等级。因此,每个套接字 8 个 mpi 等级,每个节点 16 个,每个等级 3 个线程。我认为下面的命令行应该适用

mpirun --bind-to l3 -np 16 gmx_mpi mdrun -nt 3

--bind-to 将 mpi 等级绑定到每个 L3 缓存块,-np 为每个节点分配 16 个 mpi 等级和 -nt 每个 MPI 等级 3 的线程数。是这是正确的方法吗?

如果内核能够多线程(2个线程)是不是可以这样写

mpirun --bind-to l3 -np 16 gmx_mpi mdrun -nt 6

--bind-to core 是我假设每个核心绑定一个 MPI 等级,不跨越线程,或者每个核心跨越 2 个线程以利用 MT,例如

mpirun --bind-to core -np 48 gmx_mpi mdrun -nt 2

在 2 插槽平台上每个内核 48 个列,每个内核 2 个线程 (MT)

你能确认一下吗?

我总是使用我多年前从某个地方继承的这段代码在 运行 时间打印出绑定。例如,在我的 4 核笔记本电脑上:

dsh@e7390dh:binding$ mpicc -o bind bind.c utilities.c
dsh@e7390dh:binding$ mpirun -n 4 ./bind
Rank 2 on core 2,6 of node <e7390dh>
Rank 3 on core 3,7 of node <e7390dh>
Rank 0 on core 0,4 of node <e7390dh>
Rank 1 on core 1,5 of node <e7390dh>

即每个进程都绑定到一个物理内核,但可以 运行 在任一超内核上。如果没有绑定,你会得到一个范围,例如“核心 [0-7]”。

希望这有用。

bind.c:

#include <stdio.h>
#include <mpi.h>

void printlocation();

int main(void)
{
  MPI_Init(NULL,NULL);
  printlocation();
  MPI_Finalize();
  return 0;
}

utilities.c:

#define _GNU_SOURCE
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <sched.h>

#include <mpi.h>

/* Borrowed from util-linux-2.13-pre7/schedutils/taskset.c */
static char *cpuset_to_cstr(cpu_set_t *mask, char *str)
{
    char *ptr = str;
    int i, j, entry_made = 0;
    for (i = 0; i < CPU_SETSIZE; i++) {
    if (CPU_ISSET(i, mask)) {
        int run = 0;
        entry_made = 1;
    for (j = i + 1; j < CPU_SETSIZE; j++) {
        if (CPU_ISSET(j, mask)) run++;
        else break;
        }
        if (!run)
        sprintf(ptr, "%d,", i);
        else if (run == 1) {
        sprintf(ptr, "%d,%d,", i, i + 1);
        i++;
        } else {
        sprintf(ptr, "%d-%d,", i, i + run);
        i += run;
        }
        while (*ptr != 0) ptr++;
    }
    }
    ptr -= entry_made;
    *ptr = 0;
    return(str);
}

void printlocation()
{
    int rank, namelen;
    char hnbuf[MPI_MAX_PROCESSOR_NAME];
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);    
    memset(hnbuf, 0, sizeof(hnbuf));
    MPI_Get_processor_name(hnbuf, &namelen);

    cpu_set_t coremask;
    char clbuf[7 * CPU_SETSIZE];
    memset(clbuf, 0, sizeof(clbuf));
    (void)sched_getaffinity(0, sizeof(coremask), &coremask);
    cpuset_to_cstr(&coremask, clbuf);
    printf("Rank %d on core %s of node <%s>\n", rank, clbuf, hnbuf);
}

确切的命令似乎是 --bind-to l3cache

mpirun --bind-to l3cache -np 16 gmx_mpi mdrun -nt 6