[英]Parallelize selection sort using OpenMP
我需要使用 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;
}
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)
如果您願意,您也可以以相同的方式進行“最小”縮減(顯然,更改索引和關系符號)。
選擇排序遠非最佳。 您應該使用串行的正式高效算法(例如qsort),因為它幾乎肯定會擊敗線程選擇排序以進行重要的使用。
建議合並排序的評論很好。
你在這里展示的線程選擇排序並不難,但由於這是錯誤的事情,我不會去展示它。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.