C OpenMP并行冒泡排序

时间:2011-11-03 15:39:44

标签: c openmp bubble-sort

我在C中使用OpenMP实现了并行冒泡排序算法(Odd-Even transposition sort)。然而,在我测试之后,它比串行版本慢了(大约10%),尽管我有一个4核处理器(2个真正的x 2,因为英特尔超线程)。我已经检查了核心是否实际使用,我可以在运行程序时以100%的比例看到它们。因此我认为我在实现算法时犯了一个错误。

我使用的是内核2.6.38-8-generic。

这是我编译的方式:

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个物理内核上也进行了测试 - &gt;对于一组150k的数字来说需要21s,远远低于一个核心)。但是,如果我自己设置OMP_SCHEDULE环境变量,性能会降低......

1 个答案:

答案 0 :(得分:3)

您应该对其进行分析并检查线程花费时间的位置。

一个可能的原因是并行区域不断创建和销毁;取决于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 ) {...}
}