2013-03-13 6 views
3
#include <math.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <time.h> 
#include <unistd.h> 

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

    unsigned long long in = 1; 
    unsigned long long total = 2; 
    double tol , change, new, secs , old = 0.0; 
    struct timeval start , end; 
    int threads ; /* ignored */ 

    if (argc < 2) { 
     exit (-1); 
    } 

    threads = atoi (argv[1]); 
    tol = atof (argv[2]); 
    if ((threads < 1) || (tol < 0.0)) { 
     exit (-1); 
    } 
    tol = tol *tol; 

    srand48(clock()); 
    gettimeofday (&start , NULL); 
    do 
    { 
     double x, y; 
     x = drand48(); 
     y = drand48(); 
     total ++; 
     if ((x*x + y*y) <= 1.00) 
      in ++; 
     new = 4.0 * (double)in/(double)total ; 
     change = fabs (new - old); 
     old = new; 
    }while (change > tol); 
    gettimeofday (&end, NULL); 
    secs = ((double)end.tv_sec - (double)start.tv_sec) 
    + ((double)end.tv_usec - (double)start.tv_usec)/1000000.0; 
    printf (”Found estimate of pi of %.12f in %llu iterations , %.6f seconds.n n”, 
      new, total - 2, secs); 
} 

위의 코드는 pi를 얼마나 가깝게 추정 할 수 있는지에 대한 허용 오차에 대한 인수를 취하는 순차 프로그램입니다. 이러한 이전 값과 새 값의 변경이 종료되면 허용 오차 아래로 내려갑니다.pthreads를 사용하여 pi의 몬테카를 추정을 병렬화하는 방법은 무엇입니까?

이 프로그램을 pthreads로 병렬 처리해야합니다. 나는 누군가가 나를 위해 그것을하려고 노력하는 것이 아니라 오히려 생각할 수있는 포인터와 아이디어를 얻기 위해 내가 이것을 할 수있게 할 것입니다. pthreads 프로그램은 스레드의 수와 허용 오차를 인수로 취하여 추정값을 출력합니다. 나는 프로그램을 병렬 처리하는 것에 매우 익숙하며 어디서부터 시작해야할지 모르기 때문에 조언을 구할 것입니다. 감사.

답변

0
#include <math.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <time.h> 
#include <unistd.h> 
#include <pthread.h> 

void* Function(void* i); 

#define MAX_THREADS 200 
unsigned long long total[MAX_THREADS] = {0}; //total points for threads 
unsigned long long in[MAX_THREADS] = {0};  //points inside for threads 
double tolerance, change, new, old = 0.0; 
long thread_num; 
pthread_mutex_t   mutex = PTHREAD_MUTEX_INITIALIZER; 



int main(int argc, char **argv) 
{ 
    long i; 
    struct timeval start, end; 
    double secs; 
    unsigned long long master_total; 
    pthread_t* threads; 

    if (argc != 3){ 
     printf("\nMust pass 2 arguments: (Tolerance) (# of Threads)"); 
     exit(-1); 
    } 

    thread_num = atoi (argv[1]); 
    tolerance = atof (argv[2]); 

    if ((thread_num < 1) || (tolerance < 0.0) || (thread_num > 200)) { 
     printf("\nIncorrect tolerance or threads."); 
     exit (-1); 
    } 

    threads = malloc(thread_num*sizeof(pthread_t)); //allocating space for threads 
    tolerance = tolerance * tolerance; 
    change = 0.5; 
    srand48(clock()); 
    gettimeofday (&start, NULL); 
    for(i = 0; i < thread_num; i++){ 
     pthread_create(&threads[i], NULL, Function, (void*)i); 
    } 

    for(i = 0; i < thread_num; i++){ 
     pthread_join(threads[i], NULL); 
    } 
    gettimeofday (&end, NULL); 

    master_total = 0; 
    for(i = 0; i < thread_num; i++){ 
     master_total = master_total + total[i]; 
    } 
    secs = ((double)end.tv_sec - (double)start.tv_sec) 
    + ((double)end.tv_usec - (double)start.tv_usec)/1000000.0; 
    printf ("Estimation of pi is %.12f in %llu iterations , %.6f seconds.\n", new, master_total, secs); 

} 
//Each thread will calculate it's own points for in and total 
//Per 1000 points it will calculate new and old values and compare to tolerance 
//If desired accuracy is met the threads will return. 
void* Function(void* i){ 
    /* 
    rc - return code 
    total[i], in[i] - threads own number of calculated points 
    my_total, my_in - Each thread calculates global in and total, per 1000 points and calculates tolerance 

    */ 
    long my_spot = (long) i; 
    long rc; 
    long j; 
    unsigned long long my_total; 
    unsigned long long my_in; 
    do 
    { 
     double x, y; 
     x = drand48(); 
     y = drand48(); 
     total[my_spot]++; 
     if ((x*x + y*y) <= 1.00){ 
      in[my_spot]++; 
     } 
     if(total[my_spot] % 1000 == 0){ 
      while (j < thread_num){ 
       my_total = my_total + total[j]; 
       my_in = my_in + in[j]; 
      } 
      my_total = my_total; 
     //critical section 
     //old, new, and change are all global 
     rc = pthread_mutex_lock(&mutex); 
     new = 4.0 * (double)my_in/(double)my_total; 
     change = fabs (new - old); 
     old = new; 
     rc = pthread_mutex_unlock(&mutex); 
     } 
    }while (change > tolerance); 
    return NULL; 
} 

이것은 내가 채찍질 한 것이지만 오류가 발생합니다. 그냥 멈 춥니 다. 스레드가 루프에서 빠져 나오고 주 스레드가 다시 연결됩니다. 제가 여기서 뭘하고 있는지에 대한 조언이 있습니까?

나는 그것을 실행하고 그것은 mutex 잠금에 도달하면 모든 스레드가 잠긴 것 같습니다. 각 스레드는 1000 포인트마다 pi의 변화를 확인합니다.

+0

'while (j

+0

그래, 나는 당신이 지적한 j 문제를 본다. 스레드가 다른 스레드의 합계에만 액세스하고 거기에 스레드 포인트의 로컬 합계를 추가하기 때문에 왜 (j

+0

그런 식으로 의견을 보내 주셔서 감사합니다. 그건 쉬운 실수 였어. lol –

2

각 스레드는 자체 개수 및 총 개수를 유지하고 더 나은 종료 조건을 사용해야합니다. 그런 다음 각 스레드의 in 및 total 값을 더하십시오.

+0

귀하의 조언을 통해 뭔가를 채찍질했습니다. 나는 내 자신의 질문에 대답 할 수 없기 때문에 코드를 게시 할 수 없다. 내가보기에 그것을 보낼 수있는 방법이 있을까요 아니면 내일 게시 할 수 없습니까? –

+0

@R : "더 나은 퇴장 조건"에 대한 단서를 줄 수 있는지 궁금합니다. –

+0

나는 종료 조건이 무엇인지에 대해 설명 할 수있는 자격이 충분하지 않지만 현재 상황은 본질적으로 "1/tol"반복을 작성하는 데 난독 화 된 방식 인 것처럼 보입니다. –