【MPI】并行奇偶交换排序
typedef long long __int64;
#include "mpi.h"
#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std;
int Compute_partner(int phase,int my_rank,int comm_sz){//根据趟数的奇偶性以及当前编号的编号得到partner进程的编号
int partner;
if(!(phase&1)){
if(my_rank&1){
partner=my_rank-1;
}
else{
partner=my_rank+1;
}
}
else{
if(my_rank&1){
partner=my_rank+1;
}
else{
partner=my_rank-1;
}
}
if(partner==-1 || partner==comm_sz){
partner=MPI_PROC_NULL;
}
return partner;
}
int main(int argc, char* argv[]){
int my_rank=0, comm_sz=0;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
MPI_Comm_size(MPI_COMM_WORLD, &comm_sz);
int np,n,local_n;//分别为进行奇偶交换排序的趟数和读入的数据总量以及分成的每段的长度
FILE* fp;
if(my_rank==0){
fp=fopen("Sort.txt","r");
fscanf(fp,"%d%d",&np,&n);
local_n=n/comm_sz;
}
MPI_Bcast(&np,1,MPI_INT,0,MPI_COMM_WORLD);
MPI_Bcast(&local_n,1,MPI_INT,0,MPI_COMM_WORLD);
int* keys;
int* my_keys=new int[local_n];
if(my_rank==0){
keys=new int[n];
for(int i=0;i<n;++i){
fscanf(fp,"%d",&keys[i]);
}
fclose(fp);
}
double beginTime = MPI_Wtime();
MPI_Scatter(keys,local_n,MPI_INT,my_keys,local_n,MPI_INT,0,MPI_COMM_WORLD); //sort(my_keys,my_keys+local_n);//串行快速排序 for(int i=0;i<local_n;++i){//串行奇偶交换排序
if(!(i&1)){
for(int j=0;j+1<local_n;j+=2){
if(my_keys[j]>my_keys[j+1]){
swap(my_keys[j],my_keys[j+1]);
}
}
}
else{
for(int j=1;j+1<local_n;j+=2){
if(my_keys[j]>my_keys[j+1]){
swap(my_keys[j],my_keys[j+1]);
}
}
}
} int* recv_keys=new int[local_n];
int* temp_keys=new int[local_n];
for(int i=0;i<np;++i){
int partner=Compute_partner(i, my_rank, comm_sz);
if (partner != MPI_PROC_NULL){
MPI_Sendrecv(my_keys, local_n, MPI_INT, partner, 0, recv_keys, local_n, MPI_INT, partner, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE);
if(my_rank<partner){//编号小的进程留下归并时较小的一半
int e=0,e1=0,e2=0;
int* temp_keys=new int[local_n];
while(e<local_n){
if(my_keys[e1]<=recv_keys[e2]){
temp_keys[e]=my_keys[e1];
++e;
++e1;
}
else{
temp_keys[e]=recv_keys[e2];
++e;
++e2;
}
}
for(int j=0;j<local_n;++j){
my_keys[j]=temp_keys[j];
}
}
else{//编号大的进程留下归并时较大的一半
int e=local_n-1,e1=local_n-1,e2=local_n-1;
while(e>=0){
if(my_keys[e1]>=recv_keys[e2]){
temp_keys[e]=my_keys[e1];
--e;
--e1;
}
else{
temp_keys[e]=recv_keys[e2];
--e;
--e2;
}
}
for(int j=0;j<local_n;++j){
my_keys[j]=temp_keys[j];
}
}
}
}
MPI_Gather(my_keys, local_n, MPI_INT, keys, local_n, MPI_INT, 0, MPI_COMM_WORLD);
double endTime = MPI_Wtime();
if (my_rank == 0){
for(int i=0;i<n;++i){
printf("%d ",keys[i]);
}
puts("");
printf("spent time = %lf second\n", endTime - beginTime);
}
delete[] keys;
delete[] my_keys;
delete[] recv_keys;
delete[] temp_keys;
MPI_Finalize();
return 0;
}
【MPI】并行奇偶交换排序的更多相关文章
- MPI 并行奇偶交换排序 + 集合通信函数 Sendrecv() Sendvecv_replace()
▶ <并行程序设计导论>第三章的例子程序 ● 代码 #include <stdio.h> #include <mpi.h> #include <stdlib. ...
- MPI实现并行奇偶排序
奇偶排序 odd-even-sort, using MPI 代码在 https://github.com/thkkk/odd-even-sort 使用 MPI 实现奇偶排序算法, 并且 MPI 进程 ...
- 【MPI学习6】MPI并行程序设计模式:具有不连续数据发送的MPI程序设计
基于都志辉老师<MPI并行程序设计模式>第14章内容. 前面接触到的MPI发送的数据类型都是连续型的数据.非连续类型的数据,MPI也可以发送,但是需要预先处理,大概有两类方法: (1)用户 ...
- 【MPI学习2】MPI并行程序设计模式:对等模式 & 主从模式
这里的内容主要是都志辉老师<高性能计算之并行编程技术——MPI并行程序设计> 书上有一些代码是FORTAN的,我在学习的过程中,将其都转换成C的代码,便于统一记录. 这章内容分为两个部分: ...
- C++程序中调用MPI并行的批处理命令
问题来源:在使用MPI时,将程序并行实现了,运行时需要在dos窗口下输入批处理命令,以完成程序的执行. 如:mpiexec -localroot -n 6 d:/mpi/pro.exe 但每次这样挺麻 ...
- 【MPI学习7】MPI并行程序设计模式:MPI的进程组和通信域
基于都志辉老师MPI编程书中的第15章内容. 通信域是MPI的重要概念:MPI的通信在通信域的控制和维护下进行 → 所有MPI通信任务都直接或间接用到通信域这一参数 → 对通信域的重组和划分可以方便实 ...
- 【MPI学习4】MPI并行程序设计模式:非阻塞通信MPI程序设计
这一章讲了MPI非阻塞通信的原理和一些函数接口,最后再用非阻塞通信方式实现Jacobi迭代,记录学习中的一些知识. (1)阻塞通信与非阻塞通信 阻塞通信调用时,整个程序只能执行通信相关的内容,而无法执 ...
- 学习MPI并行编程记录
简单的MPI程序示例 首先,我们来看一个简单的MPI程序实例.如同我们学习各种语言的第一个程序一样,对于MPI的第一个程序同样是"Hello Word". /* Case 1 he ...
- 【MPI学习5】MPI并行程序设计模式:组通信MPI程序设计
相关章节:第13章组通信MPI程序设计. MPI组通信与点到点通信的一个重要区别就是:组通信需要特定组内所有成员参与,而点对点通信只涉及到发送方和接收方. 由于需要组内所有成员参与,因此也是一种比较复 ...
随机推荐
- 20165227朱越 预备作业3 Linux安装及学习
预备作业3 Linux安装及学习 Linux的安装 虚拟机的安装远没有想象中的那样容易,下载还没有出现什么问题,当我安装的时候,第一个问题出现在创建虚拟机时选择安装的虚拟机版本和类型的时候的错误 当时 ...
- 遍历 USB devcie,读取设备描述符 device descriptor【转】
转自:http://blog.csdn.net/flyyyri/article/details/5480347 理论: 对于USB接口的设备,现在越来越多了.本篇我们就通过获取一个USB扫描仪设 ...
- linux下定时器介绍1
POSIX Timer 间隔定时器 setitimer 有一些重要的缺点,POSIX Timer 对 setitimer 进行了增强,克服了 setitimer 的诸多问题: 首先,一个进程同一时刻只 ...
- TreeCollection2
Tree Collection 2 Table of Contents Introduction Structure Interfaces Data Node structure Tree struc ...
- C# 序列化高级用法
using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Tex ...
- 从bind函数看js中的柯里化
以下是百度百科对柯里化函数的解释:柯里化(Currying)是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数且返回结果的新函数的技术.概念太抽象,可能 ...
- 使用qshell备份七牛云存储文件
qshell是利用七牛文档上公开的API实现的一个方便开发者测试和使用七牛API服务的命令行工具.我们可以利用它来将七牛云上存储的文件备份到本地. 它提供Mac OSX, Linux, Windows ...
- 如何学习React--[转]
如果你是一个 React (或者前端) 新手, 出于以下的原因, 你可能会对这个生态圈感到困惑: React 的目标群体历来是喜欢尝试新事物的开发者和前端专家. Facebook 只开源了他们在实际使 ...
- Jackson jsonToBean 忽略 Bean中不存在属性的匹配。
1. jsonToBean时,json中有的字段,bean中没有 无法匹配时,忽略此字段,不抛出异常(默认是抛出异常的) 方案一(局部):在class上加 @JsonIgnoreProperties( ...
- Laravel 程序架构设计思路:使用动作类
当我们谈论到应用程序的架构的时候,经常会问到一个经典的问题,那就是"这段代码应该放在哪里比较好". 因为 Laravel 是一个相当灵活的框架,所以要回答这个问题其实没那么容易.我 ...