mirror of
https://github.com/foxsen/archbase.git
synced 2026-02-03 10:24:49 +08:00
修正了并行编程基础程序里的中文标点符号
This commit is contained in:
@@ -20,7 +20,7 @@
|
||||
数据级并行性(Data Level Parallelism,简称DLP)是指对集合或者数组中的元素同时执行相同的操作。这种并行性通常来源于程序中的循环语句。下列代码块所示的代码就是一个数据并行的例子。对于数组local中的元素local[i],执行相同的操作(i+0.5)*w。可以采用将不同的数据分布到不同的处理单元的方式来实现数据级并行。
|
||||
|
||||
```c
|
||||
for(i = 0;i<N;i++){
|
||||
for(i=0;i<N;i++) {
|
||||
local[i] = (i+0.5)*w;
|
||||
}
|
||||
```
|
||||
@@ -90,7 +90,7 @@ knitr::include_graphics("images/chapter10/Shared_storage_and_message_passing_pro
|
||||
|
||||
在消息传递编程模型中,程序员需要对计算任务和数据进行划分,并安排并行程序执行过程中进程间的所有通信。在共享存储编程模型中,由于程序的多进程(或者线程)之间存在一个统一编址的共享存储空间,程序员只需进行计算任务划分,不必进行数据划分,也不用确切地知道并行程序执行过程中进程间的通信。MPP(Massive Parallel Processing)系统和机群系统往往是消息传递系统。消息传递系统的可伸缩性通常比共享存储系统要好,可支持更多处理器。
|
||||
|
||||
从进程(或者线程)间通信的角度看,消息传递并行10.6程序比共享存储并行程序复杂一些,体现在时间管理和空间管理两方面。在空间管理方面,发送数据的进程需要关心自己产生的数据被谁用到,而接收数据的进程需要关心它用到了谁产生的数据;在时间管理方面,发送数据的进程通常需要在数据被接收后才能继续,而接收数据的进程通常需要等到接收数据后才能继续。在共享存储并行程序中,各进程间的通信通过访问共享存储器完成,程序员只需考虑进程间同步,不用考虑进程间通信。尤其是比较复杂的数据结构的通信,如struct{int*pa;int* pb;int*pc;},消息传递并行程序比共享存储并行程序复杂得多。此外,对于一些在编程时难以确切知道进程间通信的程序,用消息传递的方法很难进行并行化,如{for (i,j){ x=…; y=…; a[i]\[j]=b[x]\[y];}}。这段代码中,通信特征在程序运行时才能确定,编写代码时难以确定,改写成消息传递程序就比较困难。
|
||||
从进程(或者线程)间通信的角度看,消息传递并行10.6程序比共享存储并行程序复杂一些,体现在时间管理和空间管理两方面。在空间管理方面,发送数据的进程需要关心自己产生的数据被谁用到,而接收数据的进程需要关心它用到了谁产生的数据;在时间管理方面,发送数据的进程通常需要在数据被接收后才能继续,而接收数据的进程通常需要等到接收数据后才能继续。在共享存储并行程序中,各进程间的通信通过访问共享存储器完成,程序员只需考虑进程间同步,不用考虑进程间通信。尤其是比较复杂的数据结构的通信,如struct{int*pa;int* pb;int*pc;},消息传递并行程序比共享存储并行程序复杂得多。此外,对于一些在编程时难以确切知道进程间通信的程序,用消息传递的方法很难进行并行化,如{for (i,j){ x=…; y=…; a[i]\[j]=b[x]\[y];}}。这段代码中,通信特征在程序运行时才能确定,编写代码时难以确定,改写成消息传递程序就比较困难。
|
||||
|
||||
从数据划分的角度看,消息传递并行程序必须考虑诸如数组名称以及下标变换等因素,在将一个串行程序改写成并行程序的过程中,需要修改大量的程序代码。而在共享存储编程模型中进行串行程序的并行化改写时,不用进行数组名称以及下标变换,对代码的修改量少。虽说共享存储程序无须考虑数据划分,但是在实际应用中,为了获得更高的系统性能,有时也需要考虑数据分布,使得数据尽量分布在对其进行计算的处理器上,例如OpenMP中就有进行数据分布的扩展指导。不过,相对于消息传递程序中的数据划分考虑数据分布还是要简单得多。
|
||||
|
||||
@@ -209,7 +209,7 @@ pthread_cond_wait()自动阻塞等待条件满足的现行线程,并开锁mute
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
int main(){
|
||||
int i;
|
||||
int i;
|
||||
int num_steps=1000000;
|
||||
double x,pi,step,sum=0.0;
|
||||
step = 1.0/(double) num_steps;
|
||||
@@ -218,7 +218,7 @@ int main(){
|
||||
sum = sum+4.0/(1.0+x*x);
|
||||
}
|
||||
pi = step*sum;
|
||||
printf(“pi %1f\n”, pi);
|
||||
printf("pi %1f\n", pi);
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
@@ -283,11 +283,11 @@ int main() {
|
||||
#define n 1000
|
||||
double *A,*B,*C;
|
||||
void *matrixMult(void *id) {//计算矩阵乘
|
||||
intmy_id = (int ) id;
|
||||
inti,j,k,start,end;
|
||||
int my_id = (int)id;
|
||||
int i,j,k,start,end;
|
||||
//计算进程负责的部分
|
||||
start = my_id*(n/NUM_THREADS);
|
||||
if(my_id == NUMTHREADS-1)
|
||||
if(my_id == NUM_THREADS-1)
|
||||
end = n;
|
||||
else
|
||||
end = start+(n/NUM_THREADS);
|
||||
@@ -296,11 +296,11 @@ void *matrixMult(void *id) {//计算矩阵乘
|
||||
C[i*n+j] = 0;
|
||||
for(k=0;k<n;k++)
|
||||
C[i*n+j]+=A[i*n+k]*B[k*n+j];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
inti,j;
|
||||
int i,j;
|
||||
pthread_t tids[NUM_THREADS];
|
||||
//分配数据空间
|
||||
A = (double *)malloc(sizeof(double)*n*n);
|
||||
@@ -310,7 +310,7 @@ int main() {
|
||||
for(i=0;i<n;i++)
|
||||
for(j=0;j<n;j++){
|
||||
A[i*n+j] = 1.0;
|
||||
B[i*n+j] = 1.0;
|
||||
B[i*n+j] = 1.0;
|
||||
}
|
||||
|
||||
for(i=0; i<NUM_THREADS; i++)
|
||||
@@ -559,7 +559,7 @@ reduction(reduction-identifier:list)
|
||||
#include <stdio.h>
|
||||
#include <omp.h>
|
||||
int main(){
|
||||
int i;
|
||||
int i;
|
||||
int num_steps=1000000;
|
||||
double x,pi,step,sum=0.0;
|
||||
step = 1.0/(double) num_steps;
|
||||
@@ -570,7 +570,7 @@ int main(){
|
||||
sum = sum+4.0/(1.0+x*x);
|
||||
}
|
||||
pi = step*sum;
|
||||
printf(“pi %1f\n”, pi);
|
||||
printf("pi %1f\n", pi);
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
@@ -600,7 +600,7 @@ int main()
|
||||
for(k=0;k<n;k++)
|
||||
C[i][j]+=A[i][k]*B[k][j];
|
||||
}
|
||||
Return 0;
|
||||
return 0;
|
||||
}
|
||||
```
|
||||
|
||||
@@ -664,13 +664,13 @@ OUT status status object (Status)
|
||||
以下代码是一个简单C语言的MPI程序的例子,其中MPI_COMM_WORLD是一个缺省的进程组,它指明所有的进程都参与计算。
|
||||
|
||||
```c
|
||||
#include “mpi.h”
|
||||
Int main(int argc,char *argv[])
|
||||
#include "mpi.h"
|
||||
int main(int argc,char *argv[])
|
||||
{ int myid,count;
|
||||
MPI_Init(&agrc,&argv); /*启动计算*/
|
||||
MPI_Comm_size(MPI_COMM_WORLD,&count); /*获得进程总数*/
|
||||
MPI_Comm_rank(MPI_COMM_WORLD, &myid);/*获得自己进程号*/
|
||||
printf(“I am %d of %d\n)”, myid,count); /*打印消息*/
|
||||
printf("I am %d of %d\n)", myid,count); /*打印消息*/
|
||||
MPI_Finalize();/*结束计算*/
|
||||
}
|
||||
```
|
||||
@@ -699,7 +699,7 @@ Int main(int argc,char *argv[])
|
||||
|
||||
```c
|
||||
#include <stdio.h>
|
||||
#include “mpi.h”
|
||||
#include "mpi.h"
|
||||
int main(int argc, char **argv){
|
||||
int num_steps=1000000;
|
||||
double x,pi,step,sum,sumallprocs;
|
||||
@@ -707,9 +707,9 @@ int main(int argc, char **argv){
|
||||
//进程编号及组中的进程数量, 进程编号的范围为0到num_procs-1
|
||||
int ID,num_procs;
|
||||
MPI_Status status;
|
||||
//Initialize the MPI environment
|
||||
//初始化MPI环境
|
||||
MPI_Init(&argc,&argv);
|
||||
MPI_Comm_rank(MPI_COMM_WORLD,&ID);//
|
||||
MPI_Comm_rank(MPI_COMM_WORLD,&ID);
|
||||
MPI_Comm_size(MPI_COMM_WORLD,&num_procs);
|
||||
//任务划分并计算
|
||||
step = 1.0/num_steps;
|
||||
@@ -726,7 +726,7 @@ int main(int argc, char **argv){
|
||||
MPI_Reduce(&sum,&sumallprocs,1,MPI_DOUBLE,MPI_SUM,0, MPI_COMM_WORLD);
|
||||
if(ID==0) {
|
||||
pi = sumallprocs*step;
|
||||
printf(“pi %1f\n”, pi);
|
||||
printf("pi %1f\n", pi);
|
||||
}
|
||||
MPI_Finalize();
|
||||
return 0;
|
||||
@@ -737,14 +737,14 @@ int main(int argc, char **argv){
|
||||
|
||||
```c
|
||||
#include <stdio.h>
|
||||
#include “mpi.h”
|
||||
#include "mpi.h"
|
||||
#define n 1000
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
double*A,*B,*C;
|
||||
int i,j,k;
|
||||
int ID,num_procs,line;
|
||||
MPI_Status status;
|
||||
MPI_Status status;
|
||||
|
||||
MPI_Init(&argc,&argv); //Initialize the MPI environment
|
||||
MPI_Comm_rank(MPI_COMM_WORLD,&ID);//获取当前进程号
|
||||
@@ -756,12 +756,12 @@ int main(int argc, char **argv)
|
||||
C = (double *)malloc(sizeof(double)*n*n);
|
||||
line = n/num_procs;//按进程数来划分数据
|
||||
|
||||
if(ID==0){ //节点0,主进程
|
||||
if(ID==0) { //节点0,主进程
|
||||
//初始化数组
|
||||
for(i=0;i<n;i++)
|
||||
for(j=0;j<n;j++){
|
||||
A[i*n+j] = 1.0;
|
||||
B[i*n+j] = 1.0;
|
||||
B[i*n+j] = 1.0;
|
||||
}
|
||||
//将矩阵A、B的相应数据发送给从进程
|
||||
for(i=1;i<num_procs;i++) {
|
||||
|
||||
Reference in New Issue
Block a user