2015-09-29 3 views
0

Я пытаюсь распараллелить цикл в моей программе, поэтому я искал многопоточность. Сначала я взглянул на многопоточный учебник по POSIX, это было так сложно, поэтому я попытался сделать что-то более простое. Я пробовал с OpenMP. Я успешно распараллеливал свой код, но проблема времени выполнения становится хуже, чем серийный. это ниже, чем часть моей программы. Хотел бы ты рассказать мне, в чем проблема. Должен ли я указывать, какие переменные являются общими, а какие - частными? и как я могу узнать тип каждой переменной? Я хочу, чтобы вы ответили мне, потому что я искал на многих форумах, и я до сих пор не знаю, что делать.OpenMP низкая производительность

#include <stdio.h> 
#include <math.h> 
#include <stdlib.h> 
#include <time.h> 
#include <omp.h> 
#define D    0.215   // magnetic dipolar constant 

main() 
{ 
    int  i,j,n,p,NTOT = 1600,Nc = NTOT-1; 
    float r[2],spin[2*NTOT],w[2],d; 
    double E,F,V,G,dU; 
    . 
    . 
    . 
    for(n = 1; n <= Nc; n++){ 
    fscanf(voisins,"%d%d%f%f%f",&i,&j,&r[0],&r[1],&d); 
    V = 0.0;E = 0.0;F = 0.0; 
    #pragma omp parallel num_threads(4) 
    { 
     #pragma omp for schedule(auto) 
     for(p = 0;p < 2;p++) 
     { 
     V += (D/pow(d,3.0))*(spin[2*i-2+p]-w[p])*spin[2*j-2+p]; 
     E += (spin[2*i-2+p]-w[p])*r[p]; 
     F += spin[2*j-2+p]*r[p]; 
     } 
    } 
    G = -3*(D/pow(d,5.0))*E*F; 
    dU += (V+G); 
    } 
    . 
    . 
    . 
}//End of main() 
+1

* проблема время выполнения становится хуже, чем серийный случай * Это часто является результатом использования неправильной процедуры (ы) синхронизации. Ваш код не показывает, что вы используете, лучше всего убедитесь, что это 'omp_get_wtime'. –

ответ

2

Вы распараллеливания цикл только с 2 итераций: p=0 и p=1. То, как работает OpenMP omp for, - это разделение циклов между вашими потоками в параллельной команде (которую вы определили как 4 потока) и позволяете им параллельно работать над своей частью проблемы.

Всего 2 итерации, 2 из ваших потоков будут сидеть без дела. Кроме того, на самом деле выяснить, какие потоки будут работать, какая часть проблемы требует дополнительных затрат. И если ваш фактический цикл не займет много времени (что в этом случае явно не соответствует), накладные расходы будут стоить больше, чем выгоды, которые вы получили от распараллеливания.

Лучшая стратегия, как правило, заключается в том, чтобы, по возможности, распараллеливать самые внешние контуры с помощью OpenMP, чтобы решить как проблемы разделения работы, так и сокращения (относительных) накладных расходов. Кроме того, вы можете распараллеливать на самом низком уровне цикла с помощью команды omp simd OpenMP 4.0.

И, наконец, вы не вычисляете переменные V, E и F правильно. Поскольку они суммируются с итерации на итерацию, вы должны определить их все как редукционные переменные с reduction(+:V). Я был бы удивлен, если вы в настоящее время получаете правильный ответ.

(Кроме того, как High Performance Марк говорит:.. Убедитесь, что вы синхронизация выполнения стенного время вашей программы, а не выполнение процессорного времени вашей программы Обычно это делается с omp_get_wtime())

+0

Спасибо Нос за ответ, я думаю, что это полезно. Я привязался к параллельному внешнему циклу, но в этом случае активность процессора в верхней части показала, что 45% выделено нам, 15% для sy и 40% для id, что не является случаем, когда я распараллеливаю внутренний цикл (99% для нас). Я понимаю, что вы сказали о двух простоях, но проблема времени сохраняется. Вы думаете, что я говорю, какие переменные разделены и которые являются частными, чтобы избежать условий гонки? –

+0

По умолчанию для OpenMP установлено, что каждая переменная является общей. При распараллеливании внутреннего цикла в этом случае вам нужно только указать, что 'V',' E' и 'F' являются редукционными переменными, а' p' является закрытым. – NoseKnowsAll

+0

Параллельный внешний контур (который, как я считаю, является способом перехода) потребует '#pragma omp parallel для частных (n, V, E, F, p, G) редукции (+: dU) num_threads (4)' – NoseKnowsAll

Смежные вопросы