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

如何用PThreads高效并行化奇偶换位排序算法?

高效并行化奇偶换位排序(4线程PThreads实现)

核心优化思路

原 naive 实现为每个相邻比较对创建线程,大数组下线程创建/销毁的开销远大于并行收益。要固定线程数(比如4个,匹配CPU核心数),核心是将每一轮的比较任务分片到固定线程中:

  • 奇数轮(处理索引0-1、2-3...的相邻对):把所有偶数索引开头的比较对平均分配给4个线程,每个线程负责间隔的若干组比较
  • 偶数轮(处理索引1-2、3-4...的相邻对):同理拆分奇数索引开头的比较对到4个线程
  • 用线程屏障(pthread_barrier_t)同步每一轮的奇偶步骤,确保所有线程完成当前步后再进入下一步,保证排序逻辑正确性

4线程PThreads实现代码

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

#define THREAD_COUNT 4

typedef struct {
    int* arr;
    int arr_size;
    int thread_id;
    pthread_barrier_t* barrier;
} ThreadData;

// 交换元素
void swap(int* a, int* b) {
    int temp = *a;
    *a = *b;
    *b = temp;
}

// 线程执行函数
void* oddEvenSortThread(void* arg) {
    ThreadData* data = (ThreadData*)arg;
    int* arr = data->arr;
    int arr_size = data->arr_size;
    int tid = data->thread_id;
    pthread_barrier_t* barrier = data->barrier;

    for (int k = 0; k < arr_size; k++) {
        // 奇数轮:处理偶数索引开头的相邻对(0-1, 2-3...)
        if (k % 2 == 0) {
            for (int i = tid; i < arr_size - 1; i += THREAD_COUNT * 2) {
                if (i % 2 == 0 && arr[i] > arr[i + 1]) {
                    swap(&arr[i], &arr[i + 1]);
                }
            }
        } 
        // 偶数轮:处理奇数索引开头的相邻对(1-2, 3-4...)
        else {
            for (int i = tid + 1; i < arr_size - 1; i += THREAD_COUNT * 2) {
                if (i % 2 == 1 && arr[i] > arr[i + 1]) {
                    swap(&arr[i], &arr[i + 1]);
                }
            }
        }
        // 等待所有线程完成当前轮次的比较交换
        pthread_barrier_wait(barrier);
    }

    pthread_exit(NULL);
}

// 并行奇偶排序入口函数
void parallelOddEvenSort(int* arr, int arr_size) {
    pthread_t threads[THREAD_COUNT];
    ThreadData thread_data[THREAD_COUNT];
    pthread_barrier_t barrier;

    // 初始化线程屏障
    pthread_barrier_init(&barrier, NULL, THREAD_COUNT);

    // 创建线程并分配任务
    for (int i = 0; i < THREAD_COUNT; i++) {
        thread_data[i].arr = arr;
        thread_data[i].arr_size = arr_size;
        thread_data[i].thread_id = i;
        thread_data[i].barrier = &barrier;
        pthread_create(&threads[i], NULL, oddEvenSortThread, &thread_data[i]);
    }

    // 等待所有线程执行完成
    for (int i = 0; i < THREAD_COUNT; i++) {
        pthread_join(threads[i], NULL);
    }

    // 销毁屏障
    pthread_barrier_destroy(&barrier);
}

// 测试用例
int main() {
    int arr[1000];
    // 填充随机测试数据
    for (int i = 0; i < 1000; i++) {
        arr[i] = rand() % 10000;
    }

    parallelOddEvenSort(arr, 1000);

    // 验证排序结果(可选)
    for (int i = 0; i < 999; i++) {
        if (arr[i] > arr[i + 1]) {
            printf("排序失败\n");
            return 1;
        }
    }
    printf("排序成功\n");
    return 0;
}

代码说明

  • 线程通过ThreadData结构体共享数组、线程屏障等核心资源
  • 每一轮奇偶步,线程按THREAD_COUNT * 2的步长遍历分配给自己的比较对,避免任务冲突
  • 线程屏障保证所有线程同步完成当前轮次,确保奇偶排序的全局逻辑正确

并行计算学习资料推荐

  • 《并行程序设计导论》:从基础概念到PThreads、OpenMP等主流并行API都有详细讲解,适合入门
  • 《多核与GPU编程:工具、方法及实践》:侧重实际编程技巧,包含大量并行算法的实现案例
  • MIT 6.172 并行计算机体系结构与编程:经典公开课,涵盖并行架构、算法优化等核心内容,适合系统学习

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 13:16:15