You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于OpenMP实现的冒泡排序速度比串行版本慢是什么原因?

问题根因
  • 错误嵌套并行区域:内层重复使用#pragma omp parallel for,每轮外循环都会重新创建、销毁线程池,线程调度开销远大于排序计算开销,是耗时飙升的核心原因。
  • 外循环并行错误:奇偶排序的外循环存在数据依赖,必须串行执行,外层多余的#pragma omp parallel错误地并行化了串行逻辑,导致执行逻辑混乱,额外增加同步开销。
  • 无效的reduction操作:对first变量添加的reduction(+:first)完全无意义,first仅作为每轮循环的奇偶标记,不需要归约操作,额外增加了同步开销。
  • 循环变量竞争:i、j、first变量没有声明为私有,多线程下存在数据竞争,频繁的缓存同步进一步拖慢执行速度。
修复后的代码
#include <omp.h>
#include <stdio.h>
#include <stdlib.h>

void swap(int *num1, int *num2)
{
    int temp = *num1;
    *num1 =  *num2;
    *num2 = temp;
}

int main (int argc, char *argv[]) {
    int SIZE = 5000;
    int A[SIZE];
    for(int i=0;i<SIZE;i++)
    {
        A[i] = rand()%SIZE;
    }
    int N = SIZE;
    int i=0, j=0; 
    int first;
    double start,end;
    start = omp_get_wtime();
    
    // 仅创建一次线程池
    #pragma omp parallel default(none) shared(A,N) private(i,j,first)
    {
        // 外循环必须串行,仅由单个线程执行
        #pragma omp single nowait
        {
            for( i = 0; i < N; i++ )
            {
                first = i % 2; 
                // 复用已创建的线程池并行执行内层循环,不需要再加parallel
                #pragma omp for
                for( j = first; j < N-1; j += 2 )
                {
                    if( A[ j ] > A[ j+1 ] )
                    {
                        swap( &A[ j ], &A[ j+1 ] );
                    }
                }
            }
        }
    }
    
    end = omp_get_wtime();
    for(i=0;i<N;i++)
    {
        printf(" %d",A[i]);
    }
    printf("\n-------------------------\n Time Parallel= %f",(end-start));
    return 0;
}
效果说明

修复后5000元素排序的并行耗时会下降到和串行版本相当,当数据集规模超过10万以上时,并行版本的性能优势会明显体现。

内容的提问来源于stack exchange,提问作者user3052356

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.17 19:54:03