作业二:并行排序算法

描述

使用基于oneAPI的C++/SYCL实现⼀个高效的并行归并排序。需要考虑数据的分割和合并以及线程之间的协作。

分析&示例

归并排序是⼀种分治算法,其基本原理是将待排序的数组分成两部分,分别对这两部分进行排序,然后将已排 序的子数组合并为⼀个有序数组。可考虑利用了异构并行计算的特点,将排序和合并操作分配给多个线程同时 执行,以提高排序效率。具体实现过程如下:

1. 将待排序的数组分割成多个较小的子数组,并将这些⼦数组分配给不同的线程块进行处理。

2. 每个线程块内部的线程协作完成子数组的局部排序。

3. 通过多次迭代,不断合并相邻的有序⼦数组,直到整个数组有序。

在实际实现中,归并排序可使用共享内存来加速排序过程。具体来说,可以利用共享内存来存储临时数据,减 少对全局内存的访问次数,从而提高排序的效率。另外,在合并操作中,需要考虑同步机制来保证多个线程之 间的数据⼀致性。

需要注意的是,在实际应用中,要考虑到数组大小、线程块大小、数据访问模式等因素,来设计合适的算法和 参数设置,以充分利用目标计算硬件GPU的并行计算能力,提高排序的效率和性能。

作业解答:

#include <iostream>
#include <random>
#include <CL/sycl.hpp>
#include "dpc_common.hpp"

using namespace sycl;
using namespace std;

// 初始化数组函数
void initializeArr(double* arr, int size) {
    std::random_device rd;
    std::mt19937 gen(rd());
    std::uniform_real_distribution<double> dis(1.0, 100.0);

    for (int i = 0; i < size; ++i) {
        arr[i] = dis(gen);
    }
}

// 使用 SYCL 进行并行归并排序
void ParallelMergeSortBuffer(double data_arr[], int size, queue& q) {
    buffer input(data_arr, range(size));

    // 使用 SYCL 执行并行归并排序
    for (int blockSize = 2; blockSize <= size; blockSize *= 2) {
        for (int start = 0; start < size - 1; start += 2 * blockSize) {
            int mid = std::min(start + blockSize - 1, size - 1);
            int end = std::min(start + 2 * blockSize - 1, size - 1);

            q.submit([&](handler& h) {
                accessor a(input, h);

                // 对每个块执行并行归并
                h.parallel_for(range(end - start + 1), [=](id<1> i) {
                    int leftIndex = start + i;
                    int rightIndex = mid + 1 + i;
                    double leftValue = a[leftIndex];
                    double rightValue = (rightIndex <= end) ? a[rightIndex] : a[end];

                    // 执行归并操作
                    if (leftValue > rightValue) {
                        a[leftIndex] = rightValue;
                        a[rightIndex] = leftValue;
                    }
                });
            });

            // 确保在并行操作后正确更新数据
            input.set_final_data(data_arr);
        }
    }

    // 等待队列完成
    q.wait_and_throw();
}

// 显示数组的函数
void DisplayArray(double a[], int array_size) {
    for (int i = 0; i < array_size; ++i) cout << a[i] << " ";
    cout << "\n";
}

int main() {
    int size = 256; 

    cout << "\n数组大小: " << size << "\n";

    // 在实现选择的默认设备上创建队列
    queue q;

    cout << "设备: " << q.get_device().get_info<info::device::name>() << "\n";

    // 仅为主机访问分配内存
    double* data_arr = (double*)malloc(size * sizeof(double));
    initializeArr(data_arr, size);


    // 使用 ParallelMergeSortBuffer 函数进行并行排序
    dpc_common::TimeInterval t_par;
    ParallelMergeSortBuffer(data_arr, size, q);
    cout << "并行排序时间: " << t_par.Elapsed() << " 秒\n";

    // 显示排序后的数组
    cout << "排序后的数组(并行): ";
    DisplayArray(data_arr, size);

    free(data_arr); // 释放内存

    return 0;
}

运行截图:

 

  • 11
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值