Blitz++, броненосец и OpenMP очень медленно
Я очень долго пытался научиться распараллеливать, и я читал много заметок по OpenMP. Итак, я попытался использовать его, и результаты, которые я получил, заключаются в том, что все места, где я пытался распараллелить, в 5 раз медленнее, чем последовательный случай, и мне интересно, почему...
Мой код следующий:
toevaluate
блиц-матрица из двух столбцов и строк длиной.storecallj
а такжеstorecallk
это всего лишь два блиц-вектора, которые я использовал для хранения вызовов и избежания дополнительных вызовов функций.matrix
квадратная матрица броненосца из столбцов длины (столбцы = строки), а длина строки - строки (позже я буду использовать ее для других целей, удобнее определить ее как матрицу броненосца)externfunction1
является функцией, определенной вне этого, которая вычисляет (x,y) значения функции f(a,b), где (a, b) является входом, а (x,y) является выходом.Problem
является строковой переменной иnormal
является логическимresultk
а такжеresultj
такие векторы (x,y) хранят выходные данные таких функций.externfunction2
это другая функция, определенная вне этого, которая вычисляет двойное число, вычисляя funcci (i=1,2), который является многочленом блица. Этот многочлен оценивается в double: innerprod для получения еще одного double: wvaluei (i=1,2).
Я думаю, что это все общие черты. Код ниже.
{
omp_set_dynamic(0);
OMP_NUM_THREADS=4;
omp_set_num_threads(OMP_NUM_THREADS);
int chunk = int(floor(cols/OMP_NUM_THREADS));
#pragma omp parallel shared(matrix,storecallj,toevaluate,resultj,cols,rows, storecallk,atzero,innerprod,wvalue1,wvalue2,funcc1, funcc2,storediff,checking,problem,normal,chunk) private(tid,j,k)
{
tid = omp_get_thread_num();
if (tid == 0)
{
printf("Initializing parallel process...\n");
}
#pragma omp for collapse(2) schedule (dynamic, chunk) nowait
for(j=0; j<cols; ++j)
{
for(k=0; k<rows; ++k)
{
storecallj = toevaluate(j, All);
externfunction1(problem,normal,storecallj,resultj);
storecallk = toevaluate(k, All);
storediff = storecallj-storecallk;
if(k==j){
Matrix(j,k)=-atzero*sum(resultj*resultj);
}else{
innerprod =sqrt(sum(storediff* storediff));
checking=1.0-c* innerprod;
if(checking>0.0)
{
externfunction1(problem,normal, storecallk,resultk);
externfunction2(c, innerprod, funcc1, wvalue1);
externfunction2(c, innerprod, funcc2, wvalue2);
Matrix(j,k)=-wvalue2*sum(storediff*resultj)*sum(storediff*resultk)-wvalue1*sum(resultj*resultk);
}
}
}
}
}
}
и это очень медленно. Еще одна вещь, которую я попробовал:
for(j=0; j<cols; ++j)
{
storecallj = toevaluate(j, All);
externfunction1(problem,normal,storecallj,resultj);
#pragma omp for collapse(2) schedule (dynamic, chunk) nowait
for(k=0; k<rows; ++k)
{
storecallk = toevaluate(k, All);
storediff = storecallj-storecallk;
...
Я использую динамический, потому что я должен избежать проблем в случае, если общее количество баллов для оценки не кратно 4.
Может кто-нибудь, пожалуйста, помогите мне понять, почему это так медленно?