我正在使用OpenMP并尝试使用大小为n的表获取算法前缀sum的span log(n)。对于表格的每个单元格,我都有表格的所有先前值的总和。
在我得到的解决方案中,有一个循环我无法并行化,并且我使用循环中的n个线程的数量来处理数组T的每个单元格 (所以线程号我在T [i]上工作。)
编辑:这里,顺序算法使用n个单元格的表格T进行此操作。
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 parallel ,所以创建了线程组,并且我丢失了log(n)的范围。在这段代码中,我有一个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
}
}
for循环的每个步骤都必须按顺序完成,因此我们的想法是将它们与n个线程并行化,并使所有线程在使用屏障的循环的每个步骤结束时等待。
但似乎障碍正在阻止并行性。执行显示:
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)
在您的代码中,循环迭代器i
无意间共享;
#pragma omp parallel
应
#pragma omp parallel private(i)