【问题标题】:Harmonic progression sum c++ MPI谐波级数和 c++ MPI
【发布时间】:2012-11-10 08:15:08
【问题描述】:

我正在尝试使用 MPI 制作“Harmonic Progression Sum”问题的并行版本。 但我是 MPI 新手,我不知道如何使用 MPI 运行此方法,因为它不起作用。

平行计划:

//#include "stdafx.h"
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <iostream>
#include <sstream>
#include <mpi.h>

#define d 10    //Numbers of Digits (Example: 5 => 0,xxxxx)
#define n 1000  //Value of N (Example: 5 => 1/1 + 1/2 + 1/3 + 1/4 + 1/5)

using namespace std;

int numProcess, rank, msg, source, dest, tag, qtd_elemento;

int escravo(long unsigned int *digits, int ValueEnd)
{
    MPI_Status status;

    MPI_Recv(digits, (d + 11), MPI_INT, MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status);

    for (int i = 1; i <= ValueEnd; ++i) {
        long unsigned int remainder = 1;
        for (long unsigned int digit = 0; digit < d + 11 && remainder; ++digit) {
            long unsigned int div = remainder / i;
            long unsigned int mod = remainder % i;
            digits[digit] += div;
            remainder = mod * 10;
        }
    }

    MPI_Send(&digits, 1, MPI_INT, 0, 1, MPI_COMM_WORLD);
}

void HPSSeguencial(char* output) {
    long unsigned int digits[d + 11];
    int DivN = n / 4; //Limiting slave.

    for (int digit = 0; digit < d + 11; ++digit)
        digits[digit] = 0;

    if (rank != 0){
        escravo(digits, (DivN * 1 ) );
        escravo(digits, (DivN * 2 ) );
        escravo(digits, (DivN * 3 ) );
        escravo(digits, (DivN * 4 ) );
    }

    for (int i = d + 11 - 1; i > 0; --i) {
        digits[i - 1] += digits[i] / 10;
        digits[i] %= 10;
    }
    if (digits[d + 1] >= 5) {
        ++digits[d];
    }


    for (int i = d; i > 0; --i) {
        digits[i - 1] += digits[i] / 10;
        digits[i] %= 10;
    }
    stringstream stringstreamA;
    stringstreamA << digits[0] << ",";


    for (int i = 1; i <= d; ++i) {
        stringstreamA << digits[i];
    }
    string stringA = stringstreamA.str();
    stringA.copy(output, stringA.size());
}

int main() {
    MPI_Init(&argc,&argv);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);
    MPI_Comm_size(MPI_COMM_WORLD, &numProcess);

    char output[d + 10];
    HPSSeguencial(output);
    cout << output << endl;

    MPI_Finalize();

    system("PAUSE");
    return 0;
}

原始代码

#include "stdafx.h"
#include <iostream>
#include <sstream>
#include <time.h>

#define d 10    //Numbers of Digits (Example: 5 => 0,xxxxx)
#define n 1000  //Value of N (Example: 5 => 1/1 + 1/2 + 1/3 + 1/4 + 1/5)

using namespace std;

void HPS(char* output) {
    long unsigned int digits[d + 11];

    for (int digit = 0; digit < d + 11; ++digit)
        digits[digit] = 0;

    for (int i = 1; i <= n; ++i) {
        long unsigned int remainder = 1;
        for (long unsigned int digit = 0; digit < d + 11 && remainder; ++digit) {
            long unsigned int div = remainder / i;
            long unsigned int mod = remainder % i;
            digits[digit] += div;
            remainder = mod * 10;
        }
    }


    for (int i = d + 11 - 1; i > 0; --i) {
        digits[i - 1] += digits[i] / 10;
        digits[i] %= 10;
    }
    if (digits[d + 1] >= 5) {
        ++digits[d];
    }


    for (int i = d; i > 0; --i) {
        digits[i - 1] += digits[i] / 10;
        digits[i] %= 10;
    }
    stringstream stringstreamA;
    stringstreamA << digits[0] << ",";


    for (int i = 1; i <= d; ++i) {
        stringstreamA << digits[i];
    }
    string stringA = stringstreamA.str();
    stringA.copy(output, stringA.size());
}


int main() {

    char output[d + 10];
    HPS(output);
    cout << output<< endl;

    system("PAUSE");
    return 0;
}

示例:

输入:

#define d 10
#define n 1000

输出:

7,4854708606╠╠╠╠╠╠╠╠╠╠╠╠

输入:

#define d 12
#define n 7

输出:

2,592857142857╠╠╠╠╠╠╠╠╠╠╠╠╠╠ÀÂ♂ü─¨@

问候

原始代码

http://regulus.pcs.usp.br/marathon/current/warmup.pdf

【问题讨论】:

    标签: c++ c parallel-processing mpi openmpi


    【解决方案1】:

    我假设你想并行化这部分:

    for (int i = 1; i <= ValueEnd; ++i) 
    {
            long unsigned int remainder = 1;
            for (long unsigned int digit = 0; digit < d + 11 && remainder; ++digit)
            {
                long unsigned int div = remainder / i;
                long unsigned int mod = remainder % i;
                digits[digit] += div;
                remainder = mod * 10;
            }
    }
    

    您可以按每个 MPI 进程划分每个进行迭代:

    int idP = getProcessId(), numP = numberProcess();
    for (int i = idP; i <= ValueEnd; i+=numP)
    {
      ...
    }
    

    getProcessId() 为您提供进程 ID,numberProcess() 为您提供进程号:

    int getProcessId(){
        int rank;
        MPI_Comm_rank(MPI_COMM_WORLD, &rank);
        return rank;
    }
    // Get number of process
    int numberProcess(){
        int numProc;
        MPI_Comm_size(MPI_COMM_WORLD, &numProc);
        return numProc;
    }
    

    每个进程都会有一个数组数字的副本;在并行处理之后,主进程使用MPI_reduce 从所有从属进程收集结果。或者,如果您想组合来自所有进程的值并将结果分发回所有进程,您可以使用MPI_Allreduce

     long unsigned int digits[d + 11];
        int DivN = n / 4; //Limiting slave.
    
        for (int digit = 0; digit < d + 11; ++digit)
            digits[digit] = 0;
    
        if (rank != 0){
            escravo(digits, (DivN * 1 ) );
            escravo(digits, (DivN * 2 ) );
            escravo(digits, (DivN * 3 ) );
            escravo(digits, (DivN * 4 ) );
        }
    

    根据上面的代码进程0不会执行方法escravo。此外,您没有在流程之间正确分配工作。进程 1 将在方法 escravo 内从 1 到 n/4 执行 out for 循环,但随后进程 2 将从 1 到 2n/4 执行......因此,您有不同的进程执行相同的迭代,当您真正想要的是在进程之间划分这些迭代。

    【讨论】:

      猜你喜欢
      • 2012-11-12
      • 1970-01-01
      • 2023-03-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-11-01
      • 2015-08-06
      • 2022-01-13
      相关资源
      最近更新 更多