【问题标题】:mpi_run on multicore architecture --bind-to l3 or --bind-to core多核架构上的 mpi_run --bind-to l3 或 --bind-to core
【发布时间】:2021-10-13 18:55:30
【问题描述】:

我在 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)

你会确认吗?

【问题讨论】:

    标签: multithreading performance multiprocessing mpi multicore


    【解决方案1】:

    我总是使用我多年前从某个地方继承的这段代码在运行时打印出绑定。例如,在我的 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);
    }
    

    【讨论】:

      【解决方案2】:

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

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

      【讨论】:

        猜你喜欢
        • 2022-12-01
        • 1970-01-01
        • 2019-05-03
        • 2019-08-29
        • 2022-12-02
        • 2022-07-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多