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

上記のコードは、円周率をどれだけ正確に推定するかの許容誤差を引数にとる逐次プログラムです。これらの古い値と新しい値の変化が許容範囲を下回ると、終了します。

このプログラムを pthreads で並列化する必要があります。私は誰かにそれをやらせようとしているのではなく、私がこれを行うことができるように、いくつかの指針とアイデアを考えてもらいたいと思っています. pthreads プログラムは、引数としてスレッド数と許容誤差を取り、推定値を出力します。私は並列プログラムに非常に慣れておらず、どこから始めればよいか本当にわからないので、アドバイスをいたします。ありがとう。

4

2 に答える 2

2

各スレッドは、独自の in および total カウントを保持し、より適切な終了条件を使用する必要があります。次に、各スレッドの in 値と total 値を合計します。

于 2013-03-13T05:04:27.273 に答える
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;
}

これは私が作り上げたものですが、エラーが発生しています。止まるだけです。スレッドがループから抜け出して戻ってきた後、メインスレッドがそれらに参加するだけです。私がここでやっていることについて何かアドバイスはありますか?

私はそれを実行し、ミューテックスロックに達するとすべてのスレッドがロックアウトされるようです。各スレッドで 1000 ポイントごとに pi の変化をチェックします。

于 2013-03-13T17:45:25.847 に答える