2012-11-22 34 views
3

我正在嘗試使用MPI製作「諧波進度總和」問題的並行版本。 但我是MPI的新手,我不知道如何用MPI運行此方法,因爲它不起作用。諧波累進和總和C++ 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

回答

4

我假設你想並行這一部分:

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; 
     } 
} 

您可以將分別用於iteraction到每個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; 
} 

每個過程都會有數組數字的副本;在parallel for之後,主進程使用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中的out for循環,範圍從1到n/4,但是過程2將執行從1到2n/4 ...因此,你必須在執行相同iteractions不同的過程,當你想要的是真正除以iteraction中 過程。

+0

但我會繼續使用? 從屬(位數(DIVN * 1)); 從設備(數字(DIVN * 2)); 從設備(數字(DIVN * 3)); 從設備(數字(DIVN * 4)); –

+0

只有已經做的工作​​一個人嗎? o.o –

+0

良好的xD。會是什麼是正確的進程之間獨立的工作。之後collectas掌握奴隸生產,並準備 – dreamcrash