2016-07-27 58 views
-3

我正在嘗試使用多個進程來編寫Pi計算的模擬。 我有一個函數,產生從1到-1, 隨機雙x,y數字,當我試圖計算是否x^2 + y^2 < = 1, 但結果是一個巨大的數字,並且它總是大於1計算pow(double,2)給出了一個巨大的數(C)

icpi.cpp更大(主文件):

#include <mpi.h> 
#include <iostream> 
#include "main_header.h" 
#include "dynamic.h" 
using namespace std; 

int main(int argc,char *argv[]) 
{ 

int numprocs, myid, i, root = 0, pointsInCircle = 0, pointsOutOfCircle = 0; 
boolean pointInside = TRUE; 
double point[DIMENSION], scatterTable[NUMBER_OF_SLAVES][DIMENSION], pi, t1, t2; 
MPI_Init(&argc,&argv); 
MPI_Comm_rank(MPI_COMM_WORLD,&myid); 
MPI_Comm_size(MPI_COMM_WORLD,&numprocs);  
MPI_Status status; 
srand(time(NULL)); 
t1 = MPI_Wtime(); 
printf("Trying to scatter..\n"); 
fflush(stdout); 
MPI_Scatter(&scatterTable[0][0], DIMENSION, MPI_DOUBLE,  // Master process sends the first tasks to the slaves. 
    &point[0], DIMENSION, MPI_DOUBLE, root, MPI_COMM_WORLD); 
printf("Scatter successful\n"); 
fflush(stdout); 
if (myid == 0) { 
    for (i = 0; i < TOTAL_NUM_OF_POINTS; i++) { 
     MPI_Recv(&pointInside, 1, MPI_INT, MPI_ANY_SOURCE, 0, MPI_COMM_WORLD, &status); 
     if (pointInside) { 
      pointsInCircle++; 
      printf("point inside\n"); 
      fflush(stdout); 
     } 
     else { 
      pointsOutOfCircle++; 
      printf("point outside\n"); 
      fflush(stdout); 
     } 
     point[0] = randomPoint();  // X component 
     point[1] = randomPoint();  // Y component 
     printf("x = %f, y = %f\n", point[0], point[1]); 
     fflush(stdout); 
     MPI_Send(&point[DIMENSION], 2, MPI_DOUBLE, status.MPI_SOURCE, 0, MPI_COMM_WORLD); 
    } 
    point[0] = point[1] = END_OF_PI_CALC; 
    for (i = 0; i < NUMBER_OF_SLAVES; i++) 
     MPI_Send(&point[DIMENSION], 2, MPI_DOUBLE, status.MPI_SOURCE, 0, MPI_COMM_WORLD); 
    t2 = MPI_Wtime(); 
    pi = calculatePi(pointsInCircle, pointsOutOfCircle); 
    printf("Pi = %f.\n Time to calculate: %f", pi, (t2-t1)); 
} 
else { 
    while (point[0] != END_OF_PI_CALC || point[1] != END_OF_PI_CALC) { 
     pointInside = withinCircle(point[0], point[1]); 
     MPI_Send(&pointInside, 1, MPI_INT, 0, 0, MPI_COMM_WORLD); 
     MPI_Recv(&point[DIMENSION], 2, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD,  &status); 
    } 
} 

if (myid == 0) 
    MPI_Finalize(); 
return 0; 
} 

dynamic.cpp:

#include "dynamic.h" 
#include <stdio.h>; 
#include <math.h> 
boolean withinCircle(double x, double y) { 
    double result = (pow(x,(double)2) + pow(y, (double)2)); 
    printf("result = %f", result); 
    fflush(stdout); 
    if (result <= 1) 
     return TRUE; 
    return FALSE; 
} 

double randomPoint() { 
    double range = (RANDOM_MAX - RANDOM_MIN); 
    double div = RAND_MAX/range; 
    return RANDOM_MIN + (rand()/div); 
} 

double calculatePi(int pointsWithin, int pointsOutside) { 
    double pi = (pointsWithin/pointsOutside) * 4; 
    return pi; 
} 

dynamic.h:

#ifndef DYNAMIC_H 
#define DYNAMIC_H 

#include "main_header.h" 
#define TOTAL_NUM_OF_POINTS 20000 
#define NUM_OF_POINTS_TO_SEND 1 
#define RANDOM_MAX 1 
#define RANDOM_MIN -1 
#define NUMBER_OF_SLAVES 3 
#define DIMENSION 2 
#define END_OF_PI_CALC 2 

boolean withinCircle(double x, double y); 

double randomPoint(); 

double calculatePi(int pointsWithin, int pointsOutside); 

#endif DYNAMIC_H 

main_header.h:

#ifndef MAIN_H 
#define MAIN_H 

#include <time.h> 
#include <stdlib.h> 

#define TRUE 1 
#define FALSE 0 


typedef int boolean;  // Defines a boolean datatype. 

#endif MAIN_H 

例如從wmpiexec結果:

x = -0.944151, y = 0.389386 
result = 17134570711043240115048918967982918960341742262641887592820622432866394633762913354831186160392586118427086670840176838705152.000000 
point outside 

(我知道實際計算的結果可能不會是正確的,它只是一個例子)

+1

這是沒有足夠的信息來幫助你。有很多可能導致這種症狀的問題,以及您可能誤解結果的很多方法。向我們展示您的代碼,告訴我們您使用的是哪種語言,告訴我們您觀察到的具體行爲(觀察結果,而不是解釋),並告訴我們您期望發生什麼不同。 – user2357112

+0

對不起,我剛剛編輯了這個問題,希望它足夠 –

+2

什麼是'RANDOM_MAX'和'RANDOM_MIN'?你能向我們展示一個你的代碼的[MCVE](http://stackoverflow.com/help/mcve) - 足以讓我們運行它並看到問題,但仍然會盡可能多地刪除與問題無關的代碼? – user2357112

回答

0
double calculatePi(int pointsWithin, int pointsOutside) { 
    double pi = (pointsWithin/pointsOutside) * 4; 
    return pi; 
} 

這是錯誤的。發生什麼事是你在做一個整數除法,然後乘以4,然後然後把它轉換成雙精度。所以你得到地板行爲。

在進行分區之前,您需要將pointsWithinpointsOutside投到雙倍數。

(這也是錯誤的公式,但是那是另一回事。)

+0

將其更改爲: double pi =((double)pointsWithin /(double)TOTAL_NUM_OF_POINTS)* 4.0; 但我認爲這不是問題。 我在計算x^2 + y^2時弄錯了數字 –

+0

建議'double pi = 4.0 * pointsWithin/pointsOutside;'(避免投射) – chux

0

我誤用MPI_SEND和MPI_RECV,而現在它的計算功率權利。

相關問題