高性能计算(High performance computing,缩写HPC) 指通
常使用很多处理器(作为单个机器的一部分)或者某一集群
中组织的几台计算机(作为单个计算资源操作)的计算系统
和环境
floats
K | M | G | T | P | E |
---|---|---|---|---|---|
3 | 6 | 9 | 12 | 15 | 18 |
千 | 百万 | 十亿 | 万亿 | 千万亿 | 百亿亿 |
概念
MPI_Send()
MPI_Send(sendbuf,count, datatype, dest_proc,tag,comm);
MPI_Recv()
MPI_Recv(recvbuf, count, datatype,src_proc.tag,comm,&status);
问候程序
//Hello World的并行(mpi)
#include
#include
#include
int main(int argc,char *argv[])
{
int rc,i;
int comm_sz,my_rank;
char message[100];
MPI_Status status;
int MAX_STRING = 100;
rc=MPI_Init(NULL,NULL);
MPI_Comm_size(MPI_COMM_WORLD,&comm_sz);
MPI_Comm_rank(MPI_COMM_WORLD,&my_rank);
//hello ,rc=0,MPI_SUCCESS=0(输出四句)
//printf("hello ,rc=%d,MPI_SUCCESS=%d\n",rc,MPI_SUCCESS);
printf("hello ,I am %d of %d\n",my_rank,comm_sz);
if(my_rank!=0)
{
strcpy(message,"hello");
//MPI_Send(message,strlen(message)+1,MPI_CHAR,0,99,MPI_COMM_WORLD);
MPI_Send(message,MAX_STRING,MPI_CHAR,0,99,MPI_COMM_WORLD);
}
else
{
for(i=1;i<comm_sz;i++)
{
// MPI_Recv(message,100,MPI_CHAR,MPI_ANY_SOURCE,99,MPI_COMM_WORLD,MPI_STATUS_IGNORE);
MPI_Recv(message,100,MPI_CHAR,MPI_ANY_SOURCE,MPI_ANY_TAG,MPI_COMM_WORLD,&status);
printf("%s from %d\n",message,i);
}
}
MPI_Finalize();
return 0;
}
MPI_Reduce()
MPI_Reduce(send_buf,recv_buf,count,datatype,op,dest_proc,comm);
梯形积分
MPI_Scatter()
MPI_Scatter(send_buf_p,send_count,send_type,recv_buf_p,recv_count,recv_type,src_proc,comm)
MPI_Bcast()
MPI_Bcast(data_p,count,datatype,src_proc,comm);
MPI_Gather()
MPI_Gather(send_buf_p,send_count,send_type,recv_buf_p,recv_count,recv_type,dest_proc,comm)
向量相加
矩阵向量相乘
/*
* mpicc -lm -g -Wall -o ex2_tk2_1 ex2_tk2_1.c && mpiexec -n 5 ./ex2_tk2_1
*/
#include
#include
#include
double f(double x)
{
return sin(x);
}
double Trap(double a,double b,double n,double h)
{
double estimate,x;
int i;
estimate=(f(a)+f(b))/2.0;
for(i=1;i<n;i++)
{
x=a+i*h;
estimate+=f(x);
}
return estimate*h;
}
void Get_input(int my_rank,int comm_sz,double* a_p,double* b_p,int* n_p)
{
int dest;
if(my_rank==0)
{
printf("Enter a,b,and n\n");
scanf("%lf %lf %d",a_p,b_p,n_p);
for(dest=1;dest<comm_sz;dest++)
{
MPI_Send(a_p,1,MPI_DOUBLE,dest,0,MPI_COMM_WORLD);
MPI_Send(b_p,1,MPI_DOUBLE,dest,0,MPI_COMM_WORLD);
MPI_Send(n_p,1,MPI_INT,dest,0,MPI_COMM_WORLD);
}
}
else
{
MPI_Recv(a_p,1,MPI_DOUBLE,MPI_ANY_SOURCE,MPI_ANY_TAG,MPI_COMM_WORLD,MPI_STATUS_IGNORE);
MPI_Recv(b_p,1,MPI_DOUBLE,MPI_ANY_SOURCE,MPI_ANY_TAG,MPI_COMM_WORLD,MPI_STATUS_IGNORE);
MPI_Recv(n_p,1,MPI_INT,MPI_ANY_SOURCE,MPI_ANY_TAG,MPI_COMM_WORLD,MPI_STATUS_IGNORE);
}
}
int main()
{
double a=0.0,b=3.0;
int n=2048,my_rank,comm_sz,local_n,source,q,r;
double h,local_int,total_int,local_b,local_a;
MPI_Init(NULL,NULL);
MPI_Comm_rank(MPI_COMM_WORLD,&my_rank);
MPI_Comm_size(MPI_COMM_WORLD,&comm_sz);
Get_input(my_rank,comm_sz,&a,&b,&n);
h=(b-a)/n;
q=n/comm_sz;
r=n%comm_sz;
if(my_rank<r)
{
local_n=q+1;
local_a=a+my_rank*local_n*h;
local_b=local_a+local_n*h;
}
else
{
local_n=q;
local_a=a+my_rank*local_n*h+r*h;
local_b=local_a+local_n*h;
}
local_int=Trap(local_a,local_b,n,h);
if(my_rank!=0)
{
MPI_Send(&local_int,1,MPI_DOUBLE,0,0,MPI_COMM_WORLD);
}
else
{
total_int=local_int;
for(source=1;source<comm_sz;source++)
{
MPI_Recv(&local_int,1,MPI_DOUBLE,source,0,MPI_COMM_WORLD,MPI_STATUS_IGNORE);
total_int+=local_int;
}
printf("n=%d,a=%.2f b=%.2f area=%f\n",n,a,b,total_int);
}
MPI_Finalize();
return 0;
}
/*
* mpicc -lm -g -Wall -o ex3_tk1_2 ex3_tk1_2.c && mpiexec -n 5 ./ex3_tk1_2
*/
#include
#include
#include
double f(double x)
{
return sin(x);
}
double Trap(double a,double b,double n,double h)
{
double estimate,x;
int i;
estimate=(f(a)+f(b))/2.0;
for(i=1;i<n;i++)
{
x=a+i*h;
estimate+=f(x);
}
return estimate*h;
}
void Get_input1(int my_rank,int comm_sz,double* a_p,double* b_p,int* n_p)
{
if(my_rank==0)
{
printf("Enter a,b,and n\n");
scanf("%lf %lf %d",a_p,b_p,n_p);
}
MPI_Bcast(a_p,1,MPI_DOUBLE,0,MPI_COMM_WORLD);
MPI_Bcast(b_p,1,MPI_DOUBLE,0,MPI_COMM_WORLD);
MPI_Bcast(n_p,1,MPI_INT,0,MPI_COMM_WORLD);
}
int main()
{
double a=0.0,b=3.0;
int n=2048,my_rank,comm_sz,local_n;
double h,local_int,total_int,local_b,local_a;
MPI_Init(NULL,NULL);
MPI_Comm_rank(MPI_COMM_WORLD,&my_rank);
MPI_Comm_size(MPI_COMM_WORLD,&comm_sz);
Get_input1(my_rank,comm_sz,&a,&b,&n);
h=(b-a)/n;
local_n=n/comm_sz;
local_a=a+my_rank*local_n*h;
local_b=local_a+local_n*h;
local_int=Trap(local_a,local_b,n,h);
MPI_Reduce(&local_int, &total_int, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
//MPI_Allreduce(&local_int, &total_int, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
if(my_rank==0)
{
printf("n=%d,a=%.2f b=%.2f area=%f\n",n,a,b,total_int);
}
MPI_Finalize();
return 0;
}
并行计算(paralel compunting) 一个程序通过多个任务紧密协作来解决某一个问题.
分布式计算(disributed computing指一个程序需要与其它程序协作来解决某个问题。
并行计算与分布式计算的区别
MPI整合多条消息数据的方式:
梯形积分派生数据类型
线性加速比相当于并行效率p/p=1
OpenMP的编译运行(共享内存系统)
重点是理解和使用常见的指令、子句和函数的功能,能够熟练应用
重点讲解了几个实例:梯形积分(多种并行形式) ,特别注意for循欢的并行
omp_get_num_threads() // 返回当前并行区域中的活动线程1쐦.
omp_get_thread_num() //返回线程号。
omp_get_wtime() //计算OpenMP并行程序花费时间
omp_set num_threads() //设置线程的数量
void omp_ init_lock(omp_ lock_ t*lock) //初始化锁
void omp destroy_lock(omp_ lock t*lock) //销毁锁
void omp_set_lock(omp_lock_t* lock) //尝试获得锁
void omp_unset_lock(omp_ lock_ t* lock) /释放锁
奇偶排序带openmp简单优化
openmp(三)π值估计
生产者消费者队列程序
临界区指的是一个访问共用资源(例如:共用设备或是共用存储器)的程序片段,而这些共用资源又无法同时被多个线程访问的特性。