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
我是 运行 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