我是一个新手,并且正在编写一些简单的代码来测试它的性能。我使用的是MacBook Pro和M1 Pro芯片(我不知道ARM架构是否导致了问题)。该代码是一个简单的Laplace方程求解器。
#include <iostream>
#include "mpi.h"
#include "Eigen/Dense"
#include <chrono>
using namespace Eigen;
using namespace std;
const size_t num = 1000UL;
MatrixXd initilize(){
MatrixXd u = MatrixXd::Zero(num, num);
u(seq(1, fix<num-2>), seq(1, fix<num-2>)).setConstant(10);
return u;
}
void laplace(MatrixXd &u){
setNbThreads(8);
MatrixXd u_old = u;
u(seq(1,last-1),seq(1,last-1)) =
(( u_old(seq(0,last-2,fix<1>),seq(1,last-1,fix<1>)) + u_old(seq(2,last,fix<1>),seq(1,last-1,fix<1>)) +
u_old(seq(1,last-1,fix<1>),seq(0,last-2,fix<1>)) + u_old(seq(1,last-1,fix<1>),seq(2,last,fix<1>)) )*4.0 +
u_old(seq(0,last-2,fix<1>),seq(0,last-2,fix<1>)) + u_old(seq(0,last-2,fix<1>),seq(2,last,fix<1>)) +
u_old(seq(2,last,fix<1>),seq(0,last-2,fix<1>)) + u_old(seq(2,last,fix<1>),seq(2,last,fix<1>)) ) /20.0;
}
int main(int argc, const char * argv[]) {
initParallel();
setNbThreads(0);
cout << nbThreads() << endl;
MatrixXd u = initilize();
auto start = std::chrono::high_resolution_clock::now();
for (auto i=0UL; i<100; i++) {
laplace(u);
}
auto stop = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(stop - start);
// cout << u(seq(0, fix<10>), seq(0, fix<10>)) << endl;
cout << "Execution time (ms): " << duration.count() << endl;
return 0;
}用gcc编译并启用OpenMPI
james@MBP14 tests % g++-11 -fopenmp -O3 -I/usr/local/include -I/opt/homebrew/Cellar/open-mpi/4.1.3/include -o test4 test.cpp直接运行二进制文件
james@MBP14 tests % ./test4
8
Execution time (ms): 273使用mpirun运行并指定8个线程
james@MBP14 tests % mpirun -np 8 test4
8
8
8
8
8
8
8
8
Execution time (ms): 348
Execution time (ms): 347
Execution time (ms): 353
Execution time (ms): 356
Execution time (ms): 350
Execution time (ms): 353
Execution time (ms): 357
Execution time (ms): 355因此,矩阵操作显然不是并行运行的,相反,每个线程都在运行相同的代码副本。
应该做些什么来解决这个问题呢?我对使用OpenMPI有什么误解吗?
发布于 2022-04-07 16:15:47
您混淆了OpenMPI和OpenMP。
-fopenmp启用了OpenMP。它是通过在代码中使用特殊的#pragma omp语句来并行化应用程序的一种方法。并行化发生在上--一个CPU (或者准确地说,是计算节点,如果计算节点有多个CPU)。这允许使用该CPU的所有核心。OpenMP不能用于在多个计算节点上并行化应用程序。要使用MPI,您需要调用“特殊”函数,并自己进行数据分发的艰苦工作。如果不这样做,用mpirun调用应用程序只会创建几个相同的进程(不是线程!)执行完全相同的计算。您还没有并行化您的应用程序,您只执行了8次。
没有启用MPI的编译器标志。MPI没有内置到任何编译器中。相反,MPI是一个标准,OpenMPI是实现该标准的一个特定库。您应该阅读一本关于MPI和OpenMPI的教程或书籍(例如,谷歌翻了这一个 )。
注意:通常,MPI库(如OpenMPI )附带了可执行文件/脚本(例如mpicc),它们的行为类似于编译器。但它们只是像gcc这样的编译器的薄包装器。这些包装器用于自动告诉实际编译器要链接的包含目录和库。但是,编译器本身对MPI一无所知。
https://stackoverflow.com/questions/71784465
复制相似问题