多线程(并行)归并排序的实现

发布时间:2026/9/6 22:41:20

多线程(并行)归并排序的实现
本文完全实现了算法导论这本书第三版27.3节详细介绍的多线程归并排序算法我们将给出多线程对应的单线程版本和多线程版本.使用以下代码的测试数据运行程序会发现多线程版本远远慢于单线程版本,主要因为排序数据量太大,chunk_size太小,需要频繁创建销毁大量线程且未使用线程池导致性能极度恶化,为了充分发挥多线程处理的优势需要尽可能避免以上几点,以下代码为了简单起见没有这样做.将并行归并排序的单线程版本转换为多线程版本是简单直接的因此最佳实践是先完成单线程版本然后修改单线程版本将其并行化(以下代码就是这样做的).C代码:#includeiostream#includevector#includerandom#includethread#includefunctionalusingnamespacestd;typedeflonglongType_Sorted;size_tfirstGE(Type_Sorted value,vectorsize_tindex_seq,vectorType_Sortedseq,size_t left,size_t right)//只要初始序列长度大于等于1则二分查找于当前序列长度为1时跳出循环{while(leftright){size_t mid(leftright)/2;if(seq[index_seq[mid-1]]value){leftmid1;}else{rightmid;}}if(seq[index_seq[left-1]]value)returnleft;returnleft1;}voidmerge(vectorsize_tindex_seq,vectorType_Sortedseq,vectorsize_tresult,size_t left_left,size_t left_right,size_t right_left,size_t right_right,size_t r_left,size_t r_right,size_t chunk_size){if(left_leftleft_right){size_t _nright_right-right_left1;size_t block_num_n/chunk_size;size_t index0;vectorthreadworkers;for(size_t j0;jblock_num;j,indexchunk_size){autot[,result,index_seq](){for(size_t k0;kchunk_size;k){result[r_leftindexk-1]index_seq[right_leftindexk-1];}};workers.emplace_back(t);}if(index!_n){autot[,result,index_seq](){for(size_t jindex;j_n;j){result[r_leftj-1]index_seq[right_leftj-1];}};workers.emplace_back(t);}for(autot:workers){t.join();}}elseif(right_leftright_right){size_t _nleft_right-left_left1;size_t block_num_n/chunk_size;size_t index0;vectorthreadworkers;for(size_t j0;jblock_num;j,indexchunk_size){autot[,result,index_seq](){for(size_t k0;kchunk_size;k){result[r_leftindexk-1]index_seq[left_leftindexk-1];}};workers.emplace_back(t);}if(index!_n){autot[,result,index_seq](){for(size_t jindex;j_n;j){result[r_leftj-1]index_seq[left_leftj-1];}};workers.emplace_back(t);}for(autot:workers){t.join();}}else{size_t mid(left_leftleft_right)/2;size_t rfirstGE(seq[index_seq[mid-1]],index_seq,seq,right_left,right_right);size_t r_pr_leftr-right_leftmid-left_left;result[r_p-1]index_seq[mid-1];void(*_ptr)(vectorsize_t,vectorType_Sorted,vectorsize_t,size_t,size_t,size_t,size_t,size_t,size_t,size_t)merge;threadt1(_ptr,ref(index_seq),ref(seq),ref(result),left_left,mid-1,right_left,r-1,r_left,r_p-1,chunk_size);merge(index_seq,seq,result,mid1,left_right,r,right_right,r_p1,r_right,chunk_size);t1.join();}}voidparallel_merge_sort(vectorsize_tindex_seq,vectorType_Sortedseq,size_t left,size_t right,vectorsize_tresult,size_t chunk_size){if(leftright)return;size_t i(leftright)/2;threadt1(parallel_merge_sort,ref(index_seq),ref(seq),left,i,ref(result),chunk_size);parallel_merge_sort(index_seq,seq,i1,right,result,chunk_size);t1.join();merge(index_seq,seq,result,left,i,i1,right,left,right,chunk_size);size_t _nright-left1;size_t block_num_n/chunk_size;size_t index0;vectorthreadworkers;for(size_t j0;jblock_num;j,indexchunk_size){autot[,result,index_seq](){for(size_t k0;kchunk_size;k){index_seq[leftindexk-1]result[leftindexk-1];}};workers.emplace_back(t);}autot[,result,index_seq](){for(size_t jindex;j_n;j){index_seq[leftj-1]result[leftj-1];}};workers.emplace_back(t);for(autot:workers){t.join();}}intmain(){constsize_t N2000;for(size_t j1;jN;j){vectorType_Sortedseq(j);for(size_t i0;iseq.size();i){seq[i]i1;}shuffle(seq.begin(),seq.end(),default_random_engine());vectorsize_tindex_seq(seq.size());for(size_t i0;iindex_seq.size();i){index_seq[i]i;}vectorsize_tresult(seq.size());parallel_merge_sort(index_seq,seq,1,seq.size(),result,3);for(size_t i0;iseq.size();i){if(seq[index_seq[i]]!i1){cerr排序结果错误!endl;exit(-1);}}cout排序结果正确! Njendl;}return0;}串行版本#includeiostream#includevector#includerandomusingnamespacestd;typedeflonglongType_Sorted;size_tfirstGE(Type_Sorted value,vectorsize_tindex_seq,vectorType_Sortedseq,size_t left,size_t right)//只要初始序列长度大于等于1则二分查找于当前序列长度为1时跳出循环{while(leftright){size_t mid(leftright)/2;if(seq[index_seq[mid-1]]value){leftmid1;}else{rightmid;}}if(seq[index_seq[left-1]]value)returnleft;returnleft1;}voidmerge(vectorsize_tindex_seq,vectorType_Sortedseq,vectorsize_tresult,size_t left_left,size_t left_right,size_t right_left,size_t right_right,size_t r_left,size_t r_right,size_t chunk_size){if(left_leftleft_right){size_t _nright_right-right_left1;size_t block_num_n/chunk_size;size_t index0;for(size_t j0;jblock_num;j,indexchunk_size){for(size_t k0;kchunk_size;k){result[r_leftindexk-1]index_seq[right_leftindexk-1];}}for(size_t jindex;j_n;j){result[r_leftj-1]index_seq[right_leftj-1];}}elseif(right_leftright_right){size_t _nleft_right-left_left1;size_t block_num_n/chunk_size;size_t index0;for(size_t j0;jblock_num;j,indexchunk_size){for(size_t k0;kchunk_size;k){result[r_leftindexk-1]index_seq[left_leftindexk-1];}}for(size_t jindex;j_n;j){result[r_leftj-1]index_seq[left_leftj-1];}}else{size_t mid(left_leftleft_right)/2;size_t rfirstGE(seq[index_seq[mid-1]],index_seq,seq,right_left,right_right);size_t r_pr_leftr-right_leftmid-left_left;result[r_p-1]index_seq[mid-1];merge(index_seq,seq,result,left_left,mid-1,right_left,r-1,r_left,r_p-1,chunk_size);merge(index_seq,seq,result,mid1,left_right,r,right_right,r_p1,r_right,chunk_size);}}voidparallel_merge_sort(vectorsize_tindex_seq,vectorType_Sortedseq,size_t left,size_t right,vectorsize_tresult,size_t chunk_size2){if(leftright)return;size_t i(leftright)/2;parallel_merge_sort(index_seq,seq,left,i,result);parallel_merge_sort(index_seq,seq,i1,right,result);merge(index_seq,seq,result,left,i,i1,right,left,right,chunk_size);size_t _nright-left1;size_t block_num_n/chunk_size;size_t index0;for(size_t j0;jblock_num;j,indexchunk_size){for(size_t k0;kchunk_size;k){index_seq[leftindexk-1]result[leftindexk-1];}}for(size_t jindex;j_n;j){index_seq[leftj-1]result[leftj-1];}}intmain(){constsize_t N2000;for(size_t j1;jN;j){vectorType_Sortedseq(j);for(size_t i0;iseq.size();i){seq[i]i1;}shuffle(seq.begin(),seq.end(),default_random_engine());vectorsize_tindex_seq(seq.size());for(size_t i0;iindex_seq.size();i){index_seq[i]i;}vectorsize_tresult(seq.size());parallel_merge_sort(index_seq,seq,1,seq.size(),result);for(size_t i0;iseq.size();i){if(seq[index_seq[i]]!i1){cerr排序结果错误!endl;exit(-1);}}cout排序结果正确!endl;}return0;}

相关新闻

地下车库结构设计实战要点:从荷载取值到抗浮与人防

地下车库结构设计实战要点:从荷载取值到抗浮与人防

2026/9/6 22:41:20

简介:《地下车库建筑结构设计》是一份面向土木工程专业及结构设计初学者的毕业设计说明文档,展示框架结构下集停车与儿童乐园于一体的单建式地下空间方案,可帮助读者理解车库功能分区、交通疏散、防水防灾等建筑重点,以及顶板、次…

OTFS-NOMA双域资源分配联合优化:从原理到复现实践

OTFS-NOMA双域资源分配联合优化:从原理到复现实践

2026/9/6 22:31:20

简介:面向通信工程研究人员、研究生及无线通信系统优化工程师,这是一份基于OTFS-NOMA的双域资源分配优化论文复现资源,聚焦高速用户(HSU)与低速用户(LSU)共存场景下的系统总速率最大化问题。资源以单个PDF文件(共1个文件&#xff…

GitHub CLI 发布流程深度解析:cli/cli 的跨平台构建、签名、公证与包仓库发布机制

GitHub CLI 发布流程深度解析:cli/cli 的跨平台构建、签名、公证与包仓库发布机制

2026/9/6 22:31:20

GitHub CLI 发布流程深度解析:cli/cli 的跨平台构建、签名、公证与包仓库发布机制 【免费下载链接】cli GitHub’s official command line tool 项目地址: https://gitcode.com/GitHub_Trending/cli/cli 本文基于 cli/cli 仓库中的 docs/release-process-dee…

ChCore操作系统实验全解析:从启动到虚拟内存与异常处理

ChCore操作系统实验全解析:从启动到虚拟内存与异常处理

2026/9/6 23:51:23

简介:面向操作系统课程设计与实践备考的完整实验方案,围绕上海交通大学Chcore操作系统教学环境,覆盖内存管理、系统调用与缺页异常两大核心模块。文档对分页机制、页表管理、内存分配与回收、内存保护、换页流程以及系统调用、缺页处理、页替…

把树莓派装进铁盒:从系统配置到长期稳定运行的完整指南

把树莓派装进铁盒:从系统配置到长期稳定运行的完整指南

2026/9/6 23:51:23

我最近在整理一块树莓派主板,准备把它塞进一个小铁盒,放在路由器旁边当一台长期运行的小型服务器。这个项目的标题叫“把树莓派装进小铁盒”,听起来像是一个动手向的硬件改造,但真正做下来你会发现,核心难点根本不在铁…

基于游戏化量子密钥分发协议科普软件设计

基于游戏化量子密钥分发协议科普软件设计

2026/9/6 23:51:23

摘 要 随着网络安全需求的不断提升,量子密钥分发(QKD)作为一种具备物理安全性的技术备受关注。BB84协议是量子通信入门教学的核心内容,但由于涉及量子比特、偏振基、随机测量等抽象概念,初学者仅通过传统文本往往难以…

基于Android的汝州青瓷博物馆文化推广APP实现

基于Android的汝州青瓷博物馆文化推广APP实现

2026/9/6 23:51:23

摘 要 本文针对汝州青瓷博物馆文化推广手段单一、受众面受限等现状,设计并实现了一套基于Android平台的文化推广APP。系统采用前后端分离的架构模式,后端基于SpringBoot框架构建,利用其强大的依赖管理与自动配置特性确保数据处理的高效性与…

虚拟机入门避坑指南:从心智模型到长期维护实践

虚拟机入门避坑指南:从心智模型到长期维护实践

2026/9/6 23:51:23

别急着先打开软件新建虚拟机。我在工作里见过太多人,包括我自己第一次接触虚拟机的时候,都是先下载一个大体积的镜像,然后不断试错,最后卡在某个报错上,对着英文弹窗发呆。 “春岚但是 vm”,这是一个很典型…

煤矿测量规程实战:从矿井定向到贯通测量的关键技术与经验

煤矿测量规程实战:从矿井定向到贯通测量的关键技术与经验

2026/9/6 23:41:23

简介:《煤矿测量规程(2011版)》文档资源是一份系统梳理煤矿测量规范与知识点总览的专业资料,面向矿山测量技术人员、安全生产管理人员、测绘专业学生及备考相关资格考试的读者,能够帮助快速建立煤矿测量知识体系&#…

中国人民大学杨琳团队《Nature Communications》 | 全球潮汐湿地土壤有机碳时空格局与环境驱动:一项2009-2020年的全球评估

中国人民大学杨琳团队《Nature Communications》 | 全球潮汐湿地土壤有机碳时空格局与环境驱动:一项2009-2020年的全球评估

2026/9/6 1:19:56

本文首发于“生态学者”!从“湿地面积”到“土壤碳密度”:为什么需要重新认识潮汐湿地蓝碳变化?潮汐湿地位于陆地与海洋的交汇地带,包括红树林、盐沼和潮滩,是全球重要的蓝碳生态系统。其土壤能够长期储存大量有机碳&a…

adb抓包

adb抓包

2026/9/6 1:19:56

前言 本文介绍如何通过 tcpdump 在 Android 手机上抓取网络数据包,并在电脑端使用 Wireshark 进行分析。适用于需要排查 App 网络请求、分析接口调用或调试网络问题的开发与测试场景。1. 手机要有 root 权限2. 下载 tcpdump3. adb push C:\Users\zhangkuixun\Downlo…

大模型推理镜像极简瘦身:从 25GB 巨无霸到 3GB 精简镜像实战

大模型推理镜像极简瘦身:从 25GB 巨无霸到 3GB 精简镜像实战

2026/9/6 1:19:56

大模型推理镜像极简瘦身:从 25GB 巨无霸到 3GB 精简镜像实战 在云原生基础设施中,容器镜像体积直接决定了服务的部署速度与弹性扩容敏捷度。对于传统的 Go / Java 微服务,镜像体积通常被严格控制在 50MB 到 200MB 以内,拉取镜像只…

远程协作的工作台整理

远程协作的工作台整理

2026/9/3 6:56:24

远程协作的工作台整理远程协作的核心不是再加一个工具,而是让交接信息足够完整。异步任务要写明目标、输入位置、完成标准和需要决策的人。 工作台的最小配置 将日程、待办、代码和沟通入口收拢到少数固定位置;通知按紧急程度分层。工作台不需要模仿办公…

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

2026/9/4 7:42:10

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

2026/9/6 23:21:51

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…