Программа OpenMP неожиданно не быстрее с большим количеством потоков - PullRequest
0 голосов
/ 01 мая 2020

Я новичок ie в OpenMP. Я пишу код для расчета значения Pi путем вычисления области функции f(x) = 4/(1+x^2). Я пытаюсь изучить эффективность с различными потоками. Ниже мой код:

int main() {
    long long num_iteration = 100000000;
    double pi = 0;
    double x_margin = 1.0 / num_iteration;
    double start_time, end_time;
    int num_threads_main = 0;
    int j = NUM_THREAD;
    int a;

    for(a = 1; a <= j; a++) {
        pi = 0.0;
        omp_set_num_threads(a);
        start_time = omp_get_wtime();

        #pragma omp parallel
        {
            int i;
            int ID = omp_get_thread_num();
            double sum = 0.0;
            int num_threads_local = omp_get_num_threads();
            double x_value = 0;

            if(ID == 0)
                num_threads_main = num_threads_local;

            for (i = ID; i < num_iteration; i = i + num_threads_local) {
                x_value = x_margin * ( i + 0.5 );
                sum = sum + ( 4.0 / (1.0 + x_value * x_value));
            }

            #pragma critical
            pi = pi + sum * x_margin;
        }

        end_time = omp_get_wtime() - start_time;
        printf("pi with 1000000000 steps is %f in %f seconds with threads %d\n", pi, end_time, num_threads_main);
    }

    return 0;
}

Однако, когда я получил странный результат:

pi with 1000000000 steps is 3.141593 in 0.333257 seconds with threads 1
pi with 1000000000 steps is 3.141593 in 0.175574 seconds with threads 2
pi with 1000000000 steps is 3.141593 in 0.177884 seconds with threads 3
pi with 1000000000 steps is 3.141593 in 0.170591 seconds with threads 4

Почему моя программа не работает быстрее, когда есть больше потоков? Я знаю, что могут быть некоторые издержки для OpenMP. Однако я сравниваю свой код с кодом Тима Маттсона для учебника OpenMP. Я нахожу довольно сходство между ними. Ниже приведен его код:

static long num_steps = 100000000;
double step;
int main ()
{
    int i,j;
    double pi, full_sum = 0.0;
    double start_time, run_time;
    double sum[MAX_THREADS];

    step = 1.0/(double) num_steps;

    for(j=1;j<=MAX_THREADS ;j++){
        omp_set_num_threads(j);
        full_sum = 0.0;
        start_time = omp_get_wtime();

        #pragma omp parallel private(i)
        {
            int id = omp_get_thread_num();
            int numthreads = omp_get_num_threads();
            double x;

            double partial_sum = 0;

            #pragma omp single
            printf(" num_threads = %d",numthreads);

            for (i=id;i< num_steps; i+=numthreads){
                x = (i+0.5)*step;
                partial_sum += + 4.0/(1.0+x*x);
            }

            #pragma omp critical
            full_sum += partial_sum;
        }

        pi = step * full_sum;
        run_time = omp_get_wtime() - start_time;
        printf("\n pi is %f in %f seconds %d threds \n ",pi,run_time,j);
    }
}

И вот его результат:

 num_threads = 1
 pi is 3.141593 in 0.483153 seconds 1 threds 
  num_threads = 2
 pi is 3.141593 in 0.305407 seconds 2 threds 
  num_threads = 3
 pi is 3.141593 in 0.246802 seconds 3 threds 
  num_threads = 4
 pi is 3.141593 in 0.204905 seconds 4 threds 

Я выполняю эксперимент на моем MacOS 10.15.3 с двухъядерным процессором Intel Core i5 с частотой 2,3 ГГц. Я что-то пропустил. Спасибо.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...