簡體   English   中英

C OpenMP 並行冒泡排序

[英]C OpenMP parallel bubble sort

我使用 OpenMP 在 C 中實現了並行冒泡排序算法(奇偶轉置排序)。 然而,在我測試它之后,它比串行版本慢(大約 10%),盡管我有一個 4 核處理器(由於英特爾超線程,2 個真實 x 2)。 我已經檢查過是否真正使用了內核,並且在運行程序時我可以看到每個內核 100%。 因此我認為我在實現算法時犯了一個錯誤。

我正在使用內核為 2.6.38-8-generic 的 linux。

這是我編譯的方式:

gcc -o bubble-sort bubble-sort.c -Wall -fopenmp

gcc -o bubble-sort bubble-sort.c -Wall -fopenmp用於串行版本

這就是我運行的方式:

./bubble-sort < in_10000 > out_10000

#include <omp.h>
#include <stdio.h>
#include <time.h>
#include <stdlib.h>

int main()
{
        int i, n, tmp, *x, changes;
        int chunk;
        scanf("%d ", &n);
        chunk = n / 4;
        x = (int*) malloc(n * sizeof(int));
        for(i = 0; i < n; ++i)
            scanf("%d ", &x[i]);
    changes = 1;
    int nr = 0;
    while(changes)
    {
    #pragma omp parallel private(tmp)
    {
            nr++;
            changes = 0;
            #pragma omp for \
                    reduction(+:changes)
            for(i = 0; i < n - 1; i = i + 2)
            {
                    if(x[i] > x[i+1] )
                    {
                            tmp = x[i];
                            x[i] = x[i+1];
                            x[i+1] = tmp;
                            ++changes;
                    }
            }
            #pragma omp for \
                    reduction(+:changes)
            for(i = 1; i < n - 1; i = i + 2)
            {
                    if( x[i] > x[i+1] )
                    {
                            tmp = x[i];
                            x[i] = x[i+1];
                            x[i+1] = tmp;
                            ++changes;
                    }
            }
    }
    }

    return 0;
}

后期編輯:

在我進行了您建議的更改后,它現在似乎運行良好。 它的擴展性也非常好(我也在 8 個物理內核上進行了測試 -> 一組 150k 數字花費了 21 秒,這遠低於一個內核)。 但是,如果我自己設置 OMP_SCHEDULE 環境變量,則性能會降低...

您應該對其進行分析並檢查線程在哪里花費時間。

一種可能的原因是並行區域不斷被創建和銷毀; 取決於 OpenMP 實現,它可能導致重新創建線程池,但好的實現可能應該處理這種情況。

一些需要剃掉的小東西:
- ok似乎完全沒有必要,您可以將循環退出條件更改為i<n-1
- 顯式屏障是不必要的 - 首先,你把它放在平行區域之外,所以它沒有意義; 其次,OpenMP 並行區域和循環在末尾具有隱式障礙;
- 至少在 while 循環內組合兩個隨后的並行區域:

#pragma omp parallel private(tmp)
{
    #pragma omp for bla-bla
    for (i=0; i<n-1; i+=2 ) {...}

    #pragma omp for bla-bla
    for (i=1; i<n-1; i+=2 ) {...}
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM