C++ 使用OpenMP并行化选择排序
我需要使用OpenMP实现一个并行选择排序算法,尽管我在SO或Internet上通常找不到太多信息 这是我的序列号:C++ 使用OpenMP并行化选择排序,c++,sorting,parallel-processing,openmp,selection-sort,C++,Sorting,Parallel Processing,Openmp,Selection Sort,我需要使用OpenMP实现一个并行选择排序算法,尽管我在SO或Internet上通常找不到太多信息 这是我的序列号: void selectionsort(int* arr, int size) { for (int i = size - 1; i > 0; --i) { int max = i; for (int j = i - 1; j >= 0; --j) { if (arr[j] >
void selectionsort(int* arr, int size)
{
for (int i = size - 1; i > 0; --i)
{
int max = i;
for (int j = i - 1; j >= 0; --j)
{
if (arr[j] > arr[max])
{
max = j;
}
}
swap(arr[i], arr[max]);
}
}
有人知道如何并行实现这种排序算法吗?至少在理论上?由于数组中的不断变化,外部for无法并行化,因此我们需要并行化内部for 因此,我们需要使用最大缩减,但由于我们不需要最大值,我们还需要该最大值的索引,我们需要声明一个接收结构的新缩减(仅在OpenMP 4.0中可用),在这里它是完全功能的:
#include <stdio.h>
#include <omp.h>
struct Compare { int val; int index; };
#pragma omp declare reduction(maximum : struct Compare : omp_out = omp_in.val > omp_out.val ? omp_in : omp_out)
void selectionsort(int* arr, int size)
{
for (int i = size - 1; i > 0; --i)
{
struct Compare max;
max.val = arr[i];
max.index = i;
#pragma omp parallel for reduction(maximum:max)
for (int j = i - 1; j >= 0; --j)
{
if (arr[j] > max.val)
{
max.val = arr[j];
max.index = j;
}
}
int tmp = arr[i];
arr[i] = max.val;
arr[max.index] = tmp;
}
}
int main()
{
int x[10] = {8,7,9,1,2,5,4,3,0,6};
selectionsort(x, 10);
for (int i = 0; i < 10; i++)
printf("%d\n", x[i]);
return 0;
}
#包括
#包括
结构比较{int val;int index;};
#pragma omp declare reduction(最大值:结构比较:omp_out=omp_in.val>omp_out.val?omp_in:omp_out)
void selectionsort(int*arr,int size)
{
对于(int i=size-1;i>0;--i)
{
结构比较最大;
最大值=arr[i];
最大指数=i;
#pragma omp并行减少(最大值:最大值)
对于(int j=i-1;j>=0;--j)
{
如果(arr[j]>最大值)
{
最大值=arr[j];
最大指数=j;
}
}
int tmp=arr[i];
arr[i]=最大值;
arr[max.index]=tmp;
}
}
int main()
{
int x[10]={8,7,9,1,2,5,4,3,0,6};
选择排序(x,10);
对于(int i=0;i<10;i++)
printf(“%d\n”,x[i]);
返回0;
}
Gabriel Garcia发布的解决方案只对自然数数组有效
如果使用此数组,则会得到错误的结果:
int x[10] = {-8,-7,-9,-1,-2,-5,-4,-3,0,-6};
削减声明:
#pragma omp declare reduction(maximum : struct Compare : omp_out = omp_in.val > omp_out.val ? omp_in : omp_out)
不指定初始值设定项子句,因此在并行循环的每次迭代中,max.val和max.index都被初始化为0,即使我们在循环之前对它们进行了初始化
有关更多信息,请参阅
正确的声明应该是:
#pragma omp declare reduction(maximum : \
struct Compare : \
omp_out = omp_in.val > omp_out.val ? omp_in : omp_out) \
initializer(omp_priv=omp_orig)
如果愿意,您也可以用同样的方法进行“最小”缩减(显然,更改索引和关系符号)。并行排序的经典方法可能是排序[0,SIZE/N][SIZE/N,2*SIZE/N]。。。。然后合并结果。另一个解决方案是在内环上使用
pragma omp
,它可以很容易地并行化。也许你找不到太多信息的原因是因为这是个糟糕的主意!