2014-10-25 3 views
1

Я использую OpenMP и пытаюсь получить журнал span (n) для суммы префикса алгоритма с таблицей размера n. Для каждой ячейки таблицы у меня есть сумма всех предыдущих значений таблицы.OpenMP: Создание потоков, параллелизм, барьер в цикле

В решении, которое у меня есть, есть цикл, который я не могу распараллелить, и я использую числа n потоков в цикле для работы в каждой ячейке массива T (поэтому число потоков i работает Т [I]).

EDIT: Здесь последовательный алгоритм для этого с таблицей T из n ячеек.

prefix_sum(int ** T, int n) 
{ 
    for(i = 2; i <= n; i *= 2) // this loop cannot be parallelized 
    { 
     for (l=1; l <= n/i; l++) // this loop can be parallelized 
     { 
      T[l*i - 1] += T[l*i - i/2 - 1]; 
     } 
    } 

     for(i = n/2; i >= 2; i /= 2) // this loop cannot be parallelized 
     { 
      for (l = 1; l < n/i; l++) // this loop can be parallelized 
      { 
       T[i*l + i/2 - 1] += T[i*l - 1]; 
      } 
     } 
    } 

    return T; 
} 

Я хочу, чтобы избежать кодирования каждого цикла, как это:

#pragma omp single 
{ 
    for (i=2; i <= n; i*=2) 
    { 
     #pragma omp parallel num_threads(n) 
     { 
      if ((omp_get_thread_num() % i) == (i - 1)) 
      { 
       T[omp_get_thread_num()] += T[omp_get_thread_num() - i/2]; 
      } 
     } 
    } 
} 

, поскольку спецификация OpenMP уведомляет, что для каждого #pragma OMP параллельно создается команда нитей, и я потерял промежуток войти (п). В этом коде у меня есть диапазон log^2 (n) с созданием потоков. Следовательно, я стараюсь делать каждый цикл, как это:

omp_set_num_threads(8); //this is a test code with 8 threads 

#pragma omp parallel 
{ 
    for (i = 0; i < 8; ++i) 
    { 
     printf("iteration : %d\n", i); 

     #pragma omp barrier 
    } 
} 

Каждый шаг для петель должны быть сделано последовательно, так что идея была распараллелить их с п нитями, и сделать все нити ждать в конце каждого шага петли с барьером.

Но кажется, что барьер останавливает параллелизм. Выполнение отображает это:

iteration : 0 
iteration : 0 
iteration : 0 
iteration : 0 
iteration : 0 
iteration : 0 
iteration : 0 
iteration : 0 
iteration : 1 
iteration : 2 
iteration : 3 
iteration : 4 
iteration : 5 
iteration : 6 
iteration : 7 
^C <- the program loops infinitely... 

Кажется, что только один поток выполняет цикл после первого барьера. Из спецификации openMP последовательность областей обрезки и встречающихся барьерных областей должна быть одинаковой для каждого потока в команде, и эта программа соблюдает это ограничение.

Так что мне интересно, если кто-то знает, как заставить потоки ждать других на каждом шаге цикла.

+0

Что вы имеете в виду "похоже барьера останавливая параллелизм."? –

+0

Когда я печатаю таблицу результатов, я вижу, что выполняется только первая итерация первого цикла, и я думаю, что есть только основной поток, выполняющий другие итерации, но поскольку он имеет число 0, это ничего не делает ... – vlnk

+0

Не могли бы вы добавить серийный код, прежде чем пытаться использовать OpenMP, чтобы мы поняли, чего вы пытаетесь достичь. –

ответ

0

В вашем коде цикла итераторе i всего общий непредвиденный;

#pragma omp parallel 

должен быть

#pragma omp parallel private(i) 

Живая демонстрация: http://melpon.org/wandbox/permlink/nE74kARjqoBjVWbr

+0

спасибо, это была проблема, и ваша демонстрация очень полезна :) – vlnk

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