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