Pi Berechnung gibt falsche Werte



  • Hallo, ich habe eine MPI-Funktion zur Berechnung der Zahl PI geschrieben. Der Serielle Code Funktioniert und sieht wie folgt aus:

    #include <ctime>
    #include <iostream>
    
    using namespace std;
    
    int main()
    {
    
    clock_t begin = clock();
    int i;
    long num_steps=1000000000;
    double step,pi;
    double x,sum=0.0;
    step=1.0/(double)num_steps;
    for(i=0;i<num_steps;i++)
    {
    x=(i+0.5)*step;
    sum=sum+4.0/(1.0+x*x);
    }
    pi=step*sum;
    clock_t end = clock();
    double elapsed_secs = double(end - begin) / CLOCKS_PER_SEC;
    cout<<"Benchmark Testumfeld: Thinkpad i5 3320m Dual Core@3.1 GHZ HT enabled"<<'\n';
    cout<<"Pi ist  "<<pi<<'\n';
    cout<<"Die Serielle Berechnung dauerte "<<elapsed_secs<<" Sekunden"<<'\n';
    return 0;
    }
    

    Der Code gibt "Pi ist 3.14... " aus.

    Den gleichen Code habe ich nun in MPI geschrieben:

    #include "mpi.h"   
    #include <ctime>
    #include <iostream>
    #include <ctime>
    
    using namespace std;
    
        static long num_steps = 1000000000;
        double step;
    
        int main (int argc, char** argv)
        {
            clock_t begin = clock();
            int i, id, num_procs;
            double x, pi, sum = 0.0;
            MPI_Init(&argc, &argv);
            step = 1.0/(double) num_steps;
    
            MPI_Comm_rank(MPI_COMM_WORLD, &id);
            MPI_Comm_size(MPI_COMM_WORLD, &num_procs);
    
            cout<<"Es wurde   "<<num_procs<<"   Prozess generiert"<<endl;
            cout<<"My ID is :  "<<id<<endl;
            for (i=(id+1);i<= num_steps; i+=num_procs){
                x = (i+0.5)*step;
                sum = sum + 4.0/(1.0+x*x);
            }
            cout<<"Pi ist vor der Reduce Operation "<<pi<<endl;
            MPI_Reduce(&sum, &pi, 1, MPI_FLOAT, MPI_SUM, 0,MPI_COMM_WORLD);
            if(id == 0){
                pi *= step;
            }
            clock_t end = clock();
            double elapsed_secs = double(end - begin) / CLOCKS_PER_SEC;
            cout<<"Pi ist nach der Reduce Operation  "<<pi<<'\n';
            cout<<"Die Parallele Berechnung dauerte "<<elapsed_secs<<" Sekunden"<<'\n';
    cout<<"Benchmark Testumfeld: Thinkpad i5 3320m Dual Core@3.1 GHZ HT enabled"<<'\n';
        return 0;
        }
    

    Die Ausgabe lautet wie folgt:

    Es wurde 1 Prozess generiert
    My ID is : 0
    Pi ist vor der Reduce Operation 2.074e-317
    Pi ist nach der Reduce Operation 1.4822e-323
    Die Parallele Berechnung dauerte 4.37859 Sekunden
    Benchmark Testumfeld: Thinkpad i5 3320m Dual Core@3.1 GHZ HT enabled

    Solange ich auf meinem Privat Rechner mit einem Prozess teste kriege ich natürlich keinen Geschwindigkeitsvorteil, doch warum wird Pi falsch berechnet? Es handelt sich doch um eine gewöhnliche serielle Berechnung oder sehe ich das falsch?



  • Ich kann dein MPI Beispiel hier gerade nicht testen aber du hast auf jeden Fall die Zeile pi=step*sum; vergessen. Außerdem ist deine for Schleife um einen Index verschoben im Vergleich zu vorher. Sollte es nicht eher for (i=id;i<num_steps; i+=num_procs) heißen?



  • Ach quatsch. Du machst ja dann MPI_Reduce mit der Summe. Aber die Ausgabe "Pi ist vor der Reduce Operation" trotzdem schonmal schwachsinn weil bis dahin pi gar nichts zugewiesen wurde. Und sollte bei dem MPI_Reduce Funktionsaufruf nicht MPI_DOUBLE als Parameter auftauchen und nicht MPI_FLOAT?



  • Danke für die Tipps. Ich konnte das Problem lösen, die Berechnung im Hostprozess ist falsch. Es muss pi=sum/step; sein und nicht pi*=sum;



  • Sicher? Wenn ich in der nicht MPI Version pi=sum/step; rechne kriege ich 3.14159e+18 raus. Also irgendwie nicht pi. Meiner Meinung nach muss es entweder pi=sum/num_steps; oder pi=sum*step; heißen. Bzw. nach deinem MPI_Reduce Aufruf steht die Summe ja in der pi Variable, also war pi *= step; schon korrekt.


Anmelden zum Antworten