Blitz ++, броненосец и OpenMP очень медленно - PullRequest
0 голосов
/ 28 августа 2018

Я очень долго пытался научиться распараллеливать, и я читал множество заметок по 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.

Может кто-нибудь помочь мне понять, почему это так медленно?

...