zoukankan      html  css  js  c++  java
  • 并行多核体系结构基础——第二章知识点和课后习题

    本书只找到pdf版本,全网没搜到答案,与老师也更多的为探讨,所以答案纯自己手写,若有错误欢迎使劲纠错

    本章理解有难度,可能是上课没好好听,下来也没好好看,题目做的甚是迷茫,感觉很不对劲 哎哎哎

    知识点回头抽时间复习再补上吧o( ̄ヘ ̄o#)

    课后习题:

    image.png

    首先复习在两个处理器上进行矩阵相乘,将二维矩阵A和B相乘,结果放入Y

    假设在不考虑性能开销和可拓展性下,矩阵乘的最内层"for k"循环进行优化。假设用一个线程执行循环的一半迭代,用另一个线程执行剩下的一半循环迭代。线程的ID为0和1

    矩阵相乘代码如下:

    #define MATRIX_DIM 500
    
    double A[MATRIX_DIM][MATRIX_DIM],
    	   B[MATRIX_DIM][MATRIX_DIM],
    	   Y[MATRIX_DIM][MATRIX_DIM];
    int i,j,k;
    
    for(i=0;i<MATRIX_DIM;i++){
    	for(j=0;j<MATRIX_DIM;j++){
    		Y[i][J]=0.0;
    		for(l=0;k<MATRIX_DIM;k++){
    			Y[i][j]+=A[i][k]*B[k][j];
    		} // for k
    	} // for j
    } // for i
    

    基于以上假定,可得到上述代码的共享存储版本

    #define MATRIX_DIM 500
    
    double A[MATRIX_DIM][MATRIX_DIM],
    	   B[MATRIX_DIM][MATRIX_DIM],
    	   Y[MATRIX_DIM][MATRIX_DIM];
    int i,j,k,tid;
    int kpriv[2],startiter[2],enditerp[2]; //kprive(k——privatization)为线程特有的循环下标变量
    
    for(i=0;i<MATRIX_DIM;i++){
    	for(j=0;j<MATRIX_DIM;j++){
    		Y[i][j]=0.0;
    
    		tid=begin_parallel(); //创建一个附加线程
    		startiter[tid]=tid*MATRIX_DIM/2;
    		enditer[tid]=startiter[tid]+MATRIX_DIM/2;
    
    		for(kpriv[tid]=startiter[tid];kpriv[tid]<enditer[tid];kpriv[tid]++){
    			begin_critical(); //临界区的开始
    				Y[i][j]+=A[i][kpriv[tid]]*B[kpriv[tid]][j];
    			end_critical(); //临界区的结束
    		} //for k
    		barrier(); //确保所有线程都到达该同步点后,才允许任何线程通过该点继续执行
    		end_paraller(); //结束附加线程
    	} //for j
    } //for i
    

    在基础上,完成课后习题的(b)部分

    将外层"for i"循环并行化,开销会有一定减少

    int i,j ,k,tid;
    float A[n][m],B[m][p],C[n][p],y[n][p]; //要计算Y=A*B+C 
    int kpriv[2],startiter[2],enditer[2];
    
    for(j=0;j<n/2;j++){
    	for(k=0;k<n/2;k++){
    		Y[i][j]=0.0;
    		tid=begin_parallel(); //创建一个附加线程
    		startiter[tid]=tid*n/2;
    		enditer[tid]=startiter[tid]+n/2;
    
    		for(kpriv[tid]=startiter[tid];kpriv[tid]<enditer[tid];kpriv[tid]++){
        		begin_critical(); //临界区的开始
        			Y[kpriv[tid]][j]+=A[kpriv[tid]][j]*B[j][j];
        		end_critical(); //临界区的结束
        	}//for i
    	} //for k
    } //for j
    Y[kpriv[tid]][j]+=C[kpriv[tid]][j];
    

    基于以上假定,可得到上述代码的消息传递版本

    #define MATRIX_DIM 500
    
    double A[MATRIX_DIM][MATRIX_DIM],
    	   B[MATRIX_DIM][MATRIX_DIM],
    	   Y[MATRIX_DIM][MATRIX_DIM];
    int i,j,k,tid;
    int startiter,enditer;
    double temp,temp2;
    
    tid=begin_parallel(); //创建一个附加线程
    startiter=tid*MATRIX_DIM/2;
    enditer=startiter+MATRIX_DIM/2;
    
    if(tid==0){
    	send(1,A[0][MATRIX_DIM/2-1]...A[MATRIX_DIM-1][MATRIX_DIM-1]);
    	send(1,B[MATRIX_DIM/2-1][0]...B[MATRIX_DIM-1][MATRIX_DIM-1]);
    }
    else{
    	recv(0,A[0][MATRIX_DIM/2-1]...A[MATRIX_DIM-1][MATRIX_DIM-1]);
    	recv(0,B[MATRIX_DIM/2-1][0]...B[MATRIX_DIM-1][MATRIX_DIM-1]);
    }
    
    for(i=0;i<MATRIX_DIM;i++){
    	for(j=0;j<MATRIX_DIM;j++){
    		Y[i][j]=0.0;
    
    		temp=Y[i][j];
    		for(k=startiter;k<enditer;k++){
    			temp+=A[i][k]*B[k][j];
    		} //for k
    		if(tid==0){
    			recv(1,&temp2);
    			Y[i][j]=temp+temp2;
    		}
    		else{
    			send(0,temp);
    		}
    	} //for j
    } //for i
    end_parallel();
    

    在基础上,完成课后习题的(a)部分

    double A[n][m],
    	   B[m][p],
    	   C[n][p]
    	   Y[n][p];
    int i,j,k,tid;
    int startiter,enditer;
    double temp,temp2;
    
    tid=begin_parallel(); //创建一个附加线程
    startiter=tid*n/2;
    enditer=startiter+n/2;
    
    if(tid==0){
    	send(1,A[n/2][0]...A[n-1][n-1]);
    	send(1,B[0][0]...B[n-1][n-1]);
    }
    else{
    	recv(0,A[n/2][0]...A[n-1][n-1]);
    	recv(0,B[0][0]...B[n-1][n-1]);
    }
    
    for(j=0;j<n/2;j++){
    	for(k=0;k<n/2;k++){
    		Y[i][j]=0.0;
    
    		temp=Y[k][j];
    		for(k=startiter;k<enditer;k++){
    			temp+=A[k][j]*B[j][j];
    		} //for i
    		if(tid==0){
    			recv(1,&temp2);
    			Y[k][j]=temp+temp2;
    		}
    		else{
    			send(0,temp);
    		}
    	} //for k
    } //for j
    end_parallel();
    
  • 相关阅读:
    QPS 与 TPS 简介
    程序员需要学多门语言吗
    Docker 常用命令
    Dockerfile
    Docker-安装与部署
    Docker 容器相关技术
    java多线程 线程八锁
    java多线程 生产者消费者案例-虚假唤醒
    ConcurrentHashMap
    原子变量与CAS算法
  • 原文地址:https://www.cnblogs.com/wangzheming35/p/15382800.html
Copyright © 2011-2022 走看看