首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用OpenMPI并行运行特征元

用OpenMPI并行运行特征元
EN

Stack Overflow用户
提问于 2022-04-07 14:57:58
回答 1查看 177关注 0票数 0

我是一个新手,并且正在编写一些简单的代码来测试它的性能。我使用的是MacBook Pro和M1 Pro芯片(我不知道ARM架构是否导致了问题)。该代码是一个简单的Laplace方程求解器。

代码语言:javascript
复制
#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

代码语言:javascript
复制
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

直接运行二进制文件

代码语言:javascript
复制
james@MBP14 tests % ./test4
8
Execution time (ms): 273

使用mpirun运行并指定8个线程

代码语言:javascript
复制
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有什么误解吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-04-07 16:15:47

您混淆了OpenMPI和OpenMP。

  • gcc旗-fopenmp启用了OpenMP。它是通过在代码中使用特殊的#pragma omp语句来并行化应用程序的一种方法。并行化发生在上--一个CPU (或者准确地说,是计算节点,如果计算节点有多个CPU)。这允许使用该CPU的所有核心。OpenMP不能用于在多个计算节点上并行化应用程序。
  • 另一方面,MPI (其中OpenMPI是一个特定的实现)可以用于在多个计算节点(大致上说,在连接的多台计算机上)上并行化代码。它还可以用于在一台计算机上并行处理多个核上的一些代码。因此,MPI更通用,但也更难使用。

要使用MPI,您需要调用“特殊”函数,并自己进行数据分发的艰苦工作。如果不这样做,用mpirun调用应用程序只会创建几个相同的进程(不是线程!)执行完全相同的计算。您还没有并行化您的应用程序,您只执行了8次。

没有启用MPI的编译器标志。MPI没有内置到任何编译器中。相反,MPI是一个标准,OpenMPI是实现该标准的一个特定库。您应该阅读一本关于MPI和OpenMPI的教程或书籍(例如,谷歌翻了这一个 )。

注意:通常,MPI库(如OpenMPI )附带了可执行文件/脚本(例如mpicc),它们的行为类似于编译器。但它们只是像gcc这样的编译器的薄包装器。这些包装器用于自动告诉实际编译器要链接的包含目录和库。但是,编译器本身对MPI一无所知。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71784465

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档