2011-12-10 33 views
1

該程序通過將隨機「飛鏢」(採樣點)投擲到長方形棋盤內的圓形或半徑= 1內來估計Pi。使用關係當多個進程初始化時,爲什麼這個程序會卡住?

Area of circle/Area of Square = Pi/4 

,我們可以使用相同的關係估計丕表示

Darts Inside Circle/Darts Outside Circle = Pi/4 

,當我在一個#define指定NDARTS程序工作正常。然而,當我指定NDARTS作爲一種價值that's read via scanf and then broadcasted,它神祕地獲取在超過一個過程是通過指定的mpirun卡:

mpirun -np 1 ./pi_montecarlo.x 

    Monte Carlo Method to estimate Pi 

Introduce Number of Darts 
10000 
    Number of processes: 1 
    Number of darts: 10000 
Known value of PI : 3.1415926535 
Estimated Value of PI : 3.1484000000 
Error Percentage : 0.21668457 
Time : 0.00060296 



mpirun -np 2 ./pi_montecarlo.x 

Monte Carlo Method to estimate Pi 

Introduce Number of Darts 
10000 
Number of processes: 2 
Number of darts: 10000 

^困在這裏。

爲什麼?這是一些特定於mpi實現的問題嗎?我應該嘗試其他MPI實現嗎(我想我正在運行lam)?你可以在自己的盒子上至少運行2個進程嗎?

/* 
mpicc -g -Wall -lm pi_montecarlo3.c -o pi_montecarlo.x 

mpirun -np 4 ./pi_montecarlo.x 
*/ 

#include <stdio.h> 
#include <stdlib.h> 
#include <math.h> 
#include <time.h> 
#include <mpi.h> 

#define MASTER 0 
#define PI 3.1415926535 

double pseudo_random (double a, double b) { 
    double r; 
    r = ((b-a) * ((double) rand()/(double) RAND_MAX)) +a; 
    return r; 
} 

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

    int proc_id, 
     n_procs, 
     llimit, 
     ulimit, 
     n_circle, 
     i;  


    double pi_current, 
      pi_sum,  
      x,   
      y,   
      z,   
      error,  
      start_time, 
      end_time; 

    struct timeval stime; 

    llimit = -1; 
    ulimit = 1; 
    n_circle =0; 

    MPI_Init(&argc, &argv); 

    MPI_Comm_rank (MPI_COMM_WORLD, &proc_id); 
    MPI_Comm_size (MPI_COMM_WORLD, &n_procs); 

    if (proc_id == MASTER){ 
     printf("\nMonte Carlo Method to estimate Pi \n\n"); 

      printf("Introduce Number of Darts \n"); 

      scanf("%lld",&NDARTS); 

     printf(" Number of processes: %d \n", n_procs); 
     printf(" Number of darts: %lld \n", NDARTS); 

      MPI_Bcast(&NDARTS, 1, MPI_LONG_LONG_INT, 0, MPI_COMM_WORLD); 

      start_time = MPI_Wtime(); 
    } 

    gettimeofday(&stime, NULL); 
    srand(stime.tv_usec * stime.tv_usec * stime.tv_usec * stime.tv_usec); 

    for (i=1; i<=NDARTS;i++){ 
     x = pseudo_random(llimit, ulimit); 
     y = pseudo_random(llimit, ulimit); 

     z = pow(x,2) + pow(y,2); 

     if (z<=1.0){ 
      n_circle++; 
     } 
    } 

    pi_current = 4.0 * (double)n_circle/(double) NDARTS; 

    MPI_Reduce (&pi_current, &pi_sum, 1, MPI_DOUBLE, MPI_SUM, MASTER, MPI_COMM_WORLD); 

     if (proc_id == MASTER) { 
     pi_sum = pi_sum/n_procs; 

     error = fabs ((pi_sum -PI)/PI) *100; 

     end_time = MPI_Wtime(); 

     printf("Known value of PI : %11.10f \n", PI); 
     printf("Estimated Value of PI : %11.10f\n", pi_sum); 
     printf("Error Percentage : %10.8f\n", error); 
     printf("Time : %10.8f\n\n", end_time - start_time); 

    } 

    MPI_Finalize(); 

    return 0; 
} 

回答

1

廣播不會將數據「推送」到其他處理器上。

幾乎所有的MPI通信都需要所有處理器的積極參與。例如,要在兩個處理器之間發送消息,發件人必須調用類似MPI_Send()的內容,並且接收者必須調用類似MPI_Recv()的內容。

集體通信也是如此;例如,你有每個人都致電MPI_Reduce()。同樣,你必須有大家呼叫MPI_Bcast(),只是一個不具有原始數據時,「接收器」太:

if (proc_id == MASTER){ 
    /* ... */ 
    scanf("%lld",&NDARTS); 
} 

MPI_Bcast(&NDARTS, 1, MPI_LONG_LONG_INT, 0, MPI_COMM_WORLD); 

if (proc_id == MASTER) { 
    start_time = MPI_Wtime(); 
} 

/* ... */ 

順便說一句,當你種子的隨機數發生器,它是否則罰款,你可能想確定種子是不同的在每個處理器上通過把proc_id在那裏某處,而不是隻指望時鐘不同,足以拋出種子...

相關問題