Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用OpenMP并行化选择排序_C++_Sorting_Parallel Processing_Openmp_Selection Sort - Fatal编程技术网

C++ 使用OpenMP并行化选择排序

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] >

我需要使用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] > 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
,它可以很容易地并行化。也许你找不到太多信息的原因是因为这是个糟糕的主意!