[英]How to parallelize do while and while loop in openmp?
我正在尝试使用OpenMP学习并行编程,我感兴趣的是并行化以下do while
循环,其中包含几个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-sort ,其中桶的数量众所周知且不经常更改。
关于您尝试并行化的示例, while
OpenMP不直接支持循环,因为迭代次数(循环行程计数)不是确定性的(否则,很容易将它们转换为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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.