Использование предложения сокращения OpenMP с вложенными циклами - PullRequest
0 голосов
/ 15 ноября 2018

У меня есть текущая версия функции:

    void*
    function(const Input_st *Data, Output_st *Image)
    {
        int i,j,r,Offset;
        omp_set_num_threads(24);
        #pragma omp parallel for schedule(static) shared(Data,Image),\ 
        private(i,j,r,Offset)
        for (i = 0; i < Data->NX; i++)
        {
            for (j = 0; j < (Data->NZ); j++)
            {
                for (r = 0; r < Data->NR; r++)
                {
                    Offset                = i*Data->NR*Data->NZ + j*Data->NR + r;
                    Image->pTime[Offset] = function2()
                }
            }
        }
        return NULL;
    }

Это работает очень хорошо, однако я хотел удалить вычисление переменной Offset и использовать указатель, указывающий на член Image->pTimeR, а затем приращение, которое может выглядеть следующим образом:

    void*
    function(const Input_st *Data, Output_st *Image)
    {
        int i, j, r;
        double *pTime = Image->pTime;
        omp_set_num_threads(24);
        #pragma omp parallel for schedule(static) shared(Data,Image),\ 
        private(i,j,r)
        for (i = 0; i < Data->NX; i++)
        {
            for (j = 0; j < (Data->NZ); j++)
            {
                for (r = 0; r < Data->NR; r++)
                {
                    *pTime = function2()
                    pTime++;
                }
            }
        }
        return NULL;
    }

Я получил ошибку Сег. Я предполагаю, что мне нужно использовать предложение reduction, например reduction(+:pTime).

  1. Во-первых, цель здесь состоит в том, чтобы ускорить работу функции, и мне интересно, значительно ли ускорится такое изменение? (Вроде меньше кеш памяти используется?)
  2. Во-вторых, что ж, я попытался сравнить его, но не смог! Я думаю, что проблему здесь можно решить с помощью предложения сокращения, но поскольку циклы вложены, проблема не так проста для меня.

1 Ответ

0 голосов
/ 15 ноября 2018

Здесь не нужно никаких оговорок reduction. Однако в настоящий момент все потоки используют один и тот же указатель и обновляют одну и ту же ячейку памяти (с условиями гонки в значении, присвоенном pTime, поэтому я подозреваю, что произошел сбой).

Таким образом, вам нужно определить свой указатель частным образом (как правило, объявив его в пределах области parallel, и установить его отдельно для каждого потока в значащее значение. Затем его можно увеличивать так, как вы хотите.

Вот как может выглядеть код после исправления (явно не проверенного):

void* function( const Input_st *Data, Output_st *Image ) {
    #pragma omp parallel for schedule( static ) num_threads( 24 )
    for ( int i = 0; i < Data->NX; i++ ) {
        double *pTime = Image->pTime + i * Data->NR * Data->NZ;
        for ( int j = 0; j < Data->NZ; j++ ) {
            for ( int r = 0; r < Data->NR; r++ ) {
                *pTime = function2();
                pTime++;
            }
        }
    }
    return NULL;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...