如何在openmp中并行化do-while和while循环
How to parallelize do while and while loop in openmp?
我正在尝试使用OpenMP学习并行编程,并且我对以下包含多个while
循环的do while
循环的并行化感兴趣:
do {
while(left < (length - 1) && data[left] <= pivot) left++;
while(right > 0 && data[right] >= pivot) right--;
/* swap elements */
if(left < right){
temp = data[left];
data[left] = data[right];
data[right] = temp;
}
} while(left < right);
实际上,我还没有弄清楚如何并行化while
和do while
循环,找不到任何具体描述如何并行化while
和do while
循环的资源。我已经找到了for
循环的指令,但我不能据此对while
和do while
循环做出任何假设。那么,你能描述一下我如何并行化我在这里提供的循环吗?
编辑
我已经将do while
循环转换为以下代码,其中仅使用for
循环。
for(i = 1; i<length-1; i++)
{
if(data[left] > pivot)
{
i = length;
}
else
{
left = i;
}
}
for(j=length-1; j > 0; j--)
{
if(data[right] < pivot)
{
j = 0;
}
else
{
right = j;
}
}
/* swap elements */
if(left < right)
{
temp = data[left];
data[left] = data[right];
data[right] = temp;
}
int leftCopy = left;
int rightCopy = right;
for(int leftCopy = left; leftCopy<right;leftCopy++)
{
for(int new_i = left; new_i<length-1; new_i++)
{
if(data[left] > pivot)
{
new_i = length;
}
else
{
left = new_i;
}
}
for(int new_j=right; new_j > 0; new_j--)
{
if(data[right] < pivot)
{
new_j = 0;
}
else
{
right = new_j;
}
}
leftCopy = left;
/* swap elements */
if(left < right)
{
temp = data[left];
data[left] = data[right];
data[right] = temp;
}
}
这段代码运行良好,产生了正确的结果,但当我试图将上述代码的部分并行化时,通过将前两个for
循环更改为以下循环:
#pragma omp parallel default(none) firstprivate(left) private(i,tid) shared(length, pivot, data)
{
#pragma omp for
for(i = 1; i<length-1; i++)
{
if(data[left] > pivot)
{
i = length;
}
else
{
left = i;
}
}
}
#pragma omp parallel default(none) firstprivate(right) private(j) shared(length, pivot, data)
{
#pragma omp for
for(j=length-1; j > 0; j--)
{
if(data[right] < pivot)
{
j = 0;
}
else
{
right = j;
}
}
}
速度比非并行代码差。请帮我找出我的问题。
感谢
首先,排序算法很难与OpenMP并行循环并行。这是因为循环跳闸计数不是确定性的,而是取决于每次迭代读取的输入设置值。
我认为data[left] <= pivot
这样的循环条件不会很好地工作,因为OpenMP库不知道如何在线程之间划分迭代空间。
如果你仍然对并行排序算法感兴趣,我建议你先阅读文献,看看那些由于其可扩展性而真正值得实现的算法。如果你只是想学习OpenMP,我建议你从更简单的算法开始,比如bucket排序,其中bucket的数量是众所周知的,并且不会经常改变。
关于您尝试并行化的示例,OpenMP不直接支持while
循环,因为迭代次数(循环行程计数)是不确定的(否则,很容易将它们转换为for循环)。因此,不可能在线程之间分配迭代。此外,while循环通常使用上一次迭代的结果来检查条件。这被称为Read after Write或true dependency,无法并行化。
如果你尽量减少omp parallel
子句的数量,你的减速问题可能会得到缓解。此外,尝试将它们从所有循环中移出。这些子句可能会创建和连接代码并行部分中使用的额外线程,这是非常昂贵的。
您仍然可以在并行块中同步线程,这样结果是相似的。事实上,默认情况下,所有线程都会在omp for
子句的末尾相互等待,因此这会使事情变得更加容易。
#pragma omp parallel default(none) firstprivate(right,left) private(i,j) shared(length, pivot, data)
{
#pragma omp for
for(i = 1; i<length-1; i++)
{
if(data[left] > pivot)
{
i = length;
}
else
{
left = i;
}
}
#pragma omp for
for(j=length-1; j > 0; j--)
{
if(data[right] < pivot)
{
j = 0;
}
else
{
right = j;
}
}
} // end omp parallel
- 为什么"do while"循环不断退出,即使条件计算结果为 false?
- 如果条件为TRUE(最佳方式?),则在do while循环中后置增量
- 即使没有满足他们的条件,我也无法通过一些 do-while 循环
- 如何使用 do while 循环确定最高值和最低值
- do while 循环中的 if 语句以 yes 或 no 结尾
- 在 C 或 C++ 中,循环可以同时具有 "do" 和"while"部分吗?
- 使用 while 或 do while 退出循环
- 带有开关语句的 do-while 循环 -- 无穷循环错误
- 为什么当我输入一个被接受的数字时,我的 do-while 循环没有中断?
- 为什么我的 Do-while 循环无法在C++中运行菜单
- 如果语句不会在 do - while 循环中运行
- 如何在c++中读取do-while循环中的空白
- 什么是'do while loop'的真实应用?
- 将嵌套的 for 循环更改为 do-while 循环
- 如何修复不会在退出选择时终止的 do-while 循环
- 为什么这个do-while循环每隔一个循环只写入数组?
- C++ do/while 循环和 if/else: 骰子游戏 -- 第 75 行错误:"Cout"之前的预期"While" -- 如何解决这个问题?
- 卡在链表中的无限 Do-while 循环中
- for(;;) vs do..while() for main program loop
- 如何修复do-while/while解析中的移位/减少冲突