如何解决使用 OpenMPI 和 OpenMP 的混合并行编程:OpenMP 线程始终使用每个节点 4 个内核中的 1 个
我使用 3 个 Raspberry PI 板创建了一个家庭集群来学习和试验混合并行编程。 我的设置如下:- 1 个 RPi3 B+(4 核)和 2 个 RPi4(每个 4 核),所有这些节点都使用交换机通过以太网连接。因此,我的集群中总共有 12 个内核。 RPI3B+被指定为node1,其余两个RPI4板分别为node2和node 3。
我使用 OpenMPI 和 OpenMP 编写了一个简单的程序,它总结了两个大向量。
代码结构如下:- 我的意图是 - 我将启动 3 个等级为 0、1 和 2 的 MPI 进程,并将它们分别绑定到节点 1、节点 2 和节点 3。从每个 MPI 进程内部,我将启动 4 个 OMP 线程,这些线程将完成对分布式向量块进行汇总并将结果返回到 0 级的工作。
虽然代码正在运行并给出了正确的结果,但我的观察是 OMP 线程没有利用节点中存在的所有 CPU 内核。使用 htop,我注意到每个节点上只有 1 个核心是 100% 加载的。
我启动程序的方式如下:- #mpirun --map-by node --display-devel-map --hostfile nodeconfig -np 3 ./addVectorsMPIHybrid 3000000 3000000
nodeconfig 只包含节点的名称,即 node1、node2 和 node3
请注意:我已验证在#pragma 并行部分中创建了 4 个 omp 线程。
谁能给我指点 - 为什么 OMP 线程没有在所有内核上运行?
我正在运行的代码:
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
#include <assert.h>
#include <omp.h>
int main(int argc,char *argv[])
{
double *v1,*v2,*resulv;
double *v1local,*v2local,*resulvlocal;
double startTime,endTime;
int rank,size;
int local_n;
int n;
int root = 0;
int provided;
if(argc <2)
{
printf("Please provide correct inputs\n");
exit(0);
}
n = atoi(argv[1]);
if(n <=0)
{
printf("Please enter valid size of vector\n");
exit(0);
}
//MPI_Init(NULL,NULL);
MPI_Init_thread(NULL,NULL,MPI_THREAD_FUNNELED,&provided);
MPI_Comm_rank(MPI_COMM_WORLD,&rank);
MPI_Comm_size(MPI_COMM_WORLD,&size);
local_n = n/size;
if(rank == 0)
{
v1 = (double *) malloc (sizeof(double) * n);
assert(v1);
v2 = (double *) malloc (sizeof(double) * n);
assert(v2);
resulv = (double *) malloc (sizeof(double) * n);
assert(resulv);
resulv[n] = {0};
for(int i=0; i<n; i++)
v1[i] = v2[i] = (double)i;
}
v1local = (double *) malloc (sizeof(double) * local_n);
assert(v1local);
v2local = (double *) malloc (sizeof(double) * local_n);
assert(v2local);
resulvlocal = (double *) malloc (sizeof(double) * local_n);
assert(resulv);
resulvlocal[local_n] = {0.0};
startTime = MPI_Wtime();
//Scatter v1
MPI_Scatter(v1,local_n,MPI_DOUBLE,v1local,root,MPI_COMM_WORLD);
MPI_Scatter(v2,v2local,MPI_COMM_WORLD);
#pragma omp parallel num_threads(4) default(none) shared(resulvlocal,v2local) firstprivate(local_n)
{
#pragma omp single
{
printf("num_threads = %d\n",omp_get_num_threads());
}
#pragma omp for
for(int i=0; i<local_n; i++)
resulvlocal[i] = v1local[i] + v2local[i];
}
MPI_Gather(resulvlocal,resulv,MPI_COMM_WORLD);
endTime = MPI_Wtime();
if(rank == 0)
{
//Display resulv
#if 0
for(int i=0; i<n; i++)
printf("%0.3f ",resulv[i]);
printf("\n");
#endif
printf("Time taken to compute is:%f in sec\n",endTime-startTime);
free(v1);
free(v2);
free(resulv);
}
free(v1local);
free(v2local);
free(resulvlocal);
MPI_Finalize();
return 0;
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。