欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

MPI并行编程入门

程序员文章站 2022-07-12 21:35:14
...

第一次使用MPICH出现的问题

  • 1 安装(或者说解压)MPICH后,需要将mpich/bin /.bashrcPATH便使exportPATH="/usr/local/bin/mpich/bin:mpich/bin添加到~/.bashrc的PATH中,方便使用它提供的编译运行命令。 例如我的 `export PATH="/usr/local/bin/mpich/bin:PATH"`
  • 2 如果编译时找不到mpi.h,需要将mpich目录下的include/添加到编译寻找头文件的路径中。
    例如:export CPLUS_INCLUDE_PATH="$CPLUS_INCLUDE_PATH:/usr/local/bin/mpich/include"
  • 3 如果编译时出现找不到lmpi等,我安装libmpich-dev后没问题了。sudo apt-get install libmpich-dev

学习完《MPI与OpenMP并行程序设计》第四章的感悟
代码先行(排版排不好了。。。)

  • mpi并行执行for循环时,为什么是`for (i = 进程id;…?
    写码测试发现:mpich机制为每个进程均匀分配任务,比如有n任务,p个进程。那么进程i(i<p)执行模p余i的的任务。
    对了,前面章节好像提到过,人懒还需多读书。把任务结点组成一个环,每次从上面截取p个结点分给p个进程。好像有这个图,大概是教材4.2章节的消息传递模型图。
  • 编译C++程序 mpic++ -o name file.cpp
    运行程序 mpirun -np 进程数 ./name
  • 代码中给出了入门的MPI提供的函数。每个进程都会从头到尾执行一遍该代码,并行执行了for循环的任务。MPI_Reduce规约时把任务输出合并到第二个参数。
#include "mpi.h"
#include <stdio.h>

int main(int argc, char* argv[])
{
    int i = -1;
    int id = -1;
    int p = -1;
    int solution = 0;
    int global_solution = 0;    
    int check_circuit(int, int);
    MPI_Init(&argc, &argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &id);
    MPI_Comm_size(MPI_COMM_WORLD, &p);
    MPI_Barrier(MPI_COMM_WORLD);
    double st = MPI_Wtime();
    for (i = 0; i < (1 << 16); i += p) {
        solution += check_circuit(id, i);
    }
    MPI_Reduce(&solution, &global_solution, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD);
    //MPI_Barrier(MPI_COMM_WORLD);
    double cost = MPI_Wtime() - st;
    printf("Process %d is done: %f\n", id, cost);
    fflush(stdout);
    MPI_Finalize();
    if (id == 0) {
        printf("%d: There are %d different solutions\n",id, global_solution);
    }

    return 0;
}

#define EXTRACT_BIT(n, i) ((n&(1<<i)) ? 1: 0)

int check_circuit(int id, int z) {
    int v[16];
    for (int i = 0; i < 16; ++i) {
        v[i] = EXTRACT_BIT(z, i);
    }
    if ((v[0]||v[1])&&(!v[1]||!v[3])&&(v[2]||v[3])
        && (!v[3]||!v[4]) &&(v[4]||!v[5])
        && (v[5]||!v[6]) && (v[5] || v[6])
        && (v[6]||!v[15]) && (v[7]||!v[8])
        && (!v[7]||!v[13]) && (v[8]||v[9])
        && (v[8]||!v[9]) && (!v[9]||!v[10])
        && (v[9]||v[11]) && (v[10]||v[11])
        && (v[12]||v[13]) && (v[13]||!v[14])
        && (v[14]||v[15])
    ) {
        // 写在一行,是为了输出显示时不断开
        printf("%d)%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d%d\n", id, v[0], v[1], v[2],
         v[3], v[4], v[5], v[6], v[7], v[8], v[9], v[10], v[11], v[12],
          v[13], v[14], v[15]);
        fflush(stdout); 
        return 1;
    }
    return 0;
}
相关标签: 并行 MPI