C OpenMP 并行冒泡排序

Posted

技术标签:

【中文标题】C OpenMP 并行冒泡排序【英文标题】:C OpenMP parallel bubble sort 【发布时间】:2011-12-21 07:29:56 【问题描述】:

我在 C 中使用 OpenMP 实现了并行冒泡排序算法 (Odd-Even transposition sort)。然而,在我测试它之后,它比串行版本慢(大约 10%),尽管我有一个 4 核处理器(2 real x 2,因为 Intel 超线程)。我已经检查过内核是否实际被使用,并且在运行程序时我可以看到它们每个都是 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 环境变量,性能会降低...

【问题讨论】:

我的四核 cpu 在 1 核上并不是很稳固。另外,你想在哪里做 scanf 并行 for 循环? 叹息。忘记 1-core 的事情:这是由于 pragma 在没有 -fopenmp 编译标志的情况下被默默忽略。傻我 我忘记删除 scanf for 循环中的并行部分(使用旧版本的代码)。这不是我测试的方式。 【参考方案1】:

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

一个可能的原因是并行区域不断创建和销毁;取决于 OpenMP 实现,它可能会导致线程池的重新创建,但好的实现应该可以处理这种情况。

一些小东西要刮掉: - ok 似乎完全没有必要,您只需将循环退出条件更改为 i&lt;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 ) ...

【讨论】:

以上是关于C OpenMP 并行冒泡排序的主要内容,如果未能解决你的问题,请参考以下文章

C语言冒泡排序。

C语言冒泡排序法代码

c语言冒泡排序最终结果错误

冒泡排序法

nodejs实现冒泡排序和快速排序

c++冒泡排序法