第三轮考核记录

一、Linux操作系统的学习

1.1 Linux下C编程

  • 掌握Linux环境下C代码的编译与调试
    编译与调试
  • C语言基础知识(就是高级程序语言设计学习的内容)
  • 目录与文件系统
    目录与文件

1.2 Linux 进程

进程

1.3 Shell入门

超算习堂 - Shell入门教程
(记录不小心贴在进程的后面了,内容基本都是上一次学习过的)

1.4 Shell编程作业

SHELL1 统计文件的行数

编写一个shell脚本以输出一个文本文件 a.txt 中的行数

#!/bin/bash

wc -l < a.txt

运行:

yang@yang-virtual-machine:~/桌面/shellwork$ vim shell1.sh
yang@yang-virtual-machine:~/桌面/shellwork$ vim a.txt
yang@yang-virtual-machine:~/桌面/shellwork$ chmod +x ./shell1.sh
yang@yang-virtual-machine:~/桌面/shellwork$ ./shell1.sh
9

SHELL2 打印文件的最后5行

查看日志的时候,经常会从文件的末尾往前查看,请编写一个shell脚本以输出一个文本文件 a.txt 中的 最后5行。

#!/bin/bash

tail -5 a.txt

运行:

yang@yang-virtual-machine:~/桌面/shellwork$ vim shell2.sh
yang@yang-virtual-machine:~/桌面/shellwork$ chmod +x ./shell2.sh
yang@yang-virtual-machine:~/桌面/shellwork$ ./shell2.sh
int a = 10;
int b = 100;
cout << "a + b:" << a + b << endl;
return 0;
}

SHELL3 监控CPU使用率

编写shell脚本,实现对后台CPU使用率的的监控,并将CPU利用率前三的进程信息存储到文件中。

#!/bin/bash
ps -aux --sort=-pcpu | head -4 >>cpu3.txt

运行:

yang@yang-virtual-machine:~/桌面$ vim cpu.sh
yang@yang-virtual-machine:~/桌面$ ./cpu.sh
bash: ./cpu.sh: 权限不够
yang@yang-virtual-machine:~/桌面$ chmod +x ./cpu.sh
yang@yang-virtual-machine:~/桌面$ ./cpu.sh
yang@yang-virtual-machine:~/桌面$ vim cpu3.txt

cpu3.txt内容:

USER         PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
yang       19504  0.5  0.7 408156 31604 ?        SNsl 21:16   0:00 /usr/libexec/tracker-extract-3
yang       19335  0.4  1.6 651096 66120 ?        Ssl  21:08   0:02 /usr/libexec/gnome-terminal-server
yang        1241  0.3  6.7 4500040 270416 ?      Ssl  19:11   0:29 /usr/bin/gnome-shell

二、入门并行编程理论学习

1. OpenMP

openmp记录

2.向量化(先了解)

向量化指令集: Mirror of Intel® Intrinsics Guide (laruence.com)

3.并行编程方法论(先了解)

观看了三个视频

三、实操优化代码

1.矩阵乘法优化

将ijk的顺序调换成ikj,然后进行并行

	#pragma omp parallel for shared(a,b,c) schedule(dynamic)
	for(int i=1;i<N;i++)
		for(int k=1;k<N;k++){
			double r=a[i][k];
			for(int j=1;j<N;j++)
				c[i][j] += r*b[k][j];
		}
yang@yang-virtual-machine:~/桌面/multiply$ ./run.sh
yang@yang-virtual-machine:~/桌面/multiply$ ./multiply
初始矩阵乘法运行耗时: 419.568744 ms
优化后矩阵乘法运行耗时: 142.873895 ms
加速比为:2.936637
yang@yang-virtual-machine:~/桌面/multiply$ ./check
CHECK:
-RIGHT-
yang@yang-virtual-machine:~/桌面/multiply$ ./multiply
初始矩阵乘法运行耗时: 475.350693 ms
优化后矩阵乘法运行耗时: 144.931256 ms
加速比为:3.279836
yang@yang-virtual-machine:~/桌面/multiply$ ./multiply
初始矩阵乘法运行耗时: 471.195179 ms
优化后矩阵乘法运行耗时: 169.307161 ms
加速比为:2.783079
yang@yang-virtual-machine:~/桌面/multiply$ ./multiply
初始矩阵乘法运行耗时: 470.299077 ms
优化后矩阵乘法运行耗时: 142.539144 ms
加速比为:3.299438
yang@yang-virtual-machine:~/桌面/multiply$ ./multiply
初始矩阵乘法运行耗时: 470.839792 ms
优化后矩阵乘法运行耗时: 143.673555 ms
加速比为:3.277150
yang@yang-virtual-machine:~/桌面/multiply$ ./multiply
初始矩阵乘法运行耗时: 464.539892 ms
优化后矩阵乘法运行耗时: 144.248768 ms
加速比为:3.220408
yang@yang-virtual-machine:~/桌面/multiply$ ./multiply
初始矩阵乘法运行耗时: 467.344651 ms
优化后矩阵乘法运行耗时: 194.237274 ms
加速比为:2.406050
yang@yang-virtual-machine:~/桌面/multiply$ ./multiply
初始矩阵乘法运行耗时: 471.485065 ms
优化后矩阵乘法运行耗时: 142.872113 ms
加速比为:3.300050
yang@yang-virtual-machine:~/桌面/multiply$ ./multiply
初始矩阵乘法运行耗时: 464.633326 ms
优化后矩阵乘法运行耗时: 143.794633 ms
加速比为:3.231229
yang@yang-virtual-machine:~/桌面/multiply$ ./multiply
初始矩阵乘法运行耗时: 452.560520 ms
优化后矩阵乘法运行耗时: 163.973108 ms
加速比为:2.759968
yang@yang-virtual-machine:~/桌面/multiply$ ./multiply
初始矩阵乘法运行耗时: 473.394464 ms
优化后矩阵乘法运行耗时: 144.675783 ms
加速比为:3.272106
yang@yang-virtual-machine:~/桌面/multiply$ ./multiply
初始矩阵乘法运行耗时: 466.829666 ms
优化后矩阵乘法运行耗时: 143.055872 ms
加速比为:3.263268
yang@yang-virtual-machine:~/桌面/multiply$ ./multiply
初始矩阵乘法运行耗时: 436.283745 ms
优化后矩阵乘法运行耗时: 149.984999 ms
加速比为:2.908849
yang@yang-virtual-machine:~/桌面/multiply$ ./multiply
初始矩阵乘法运行耗时: 461.173266 ms
优化后矩阵乘法运行耗时: 148.461904 ms
加速比为:3.106341
yang@yang-virtual-machine:~/桌面/multiply$ ./multiply
初始矩阵乘法运行耗时: 470.584852 ms
优化后矩阵乘法运行耗时: 143.420487 ms
加速比为:3.281155
yang@yang-virtual-machine:~/桌面/multiply$ ./multiply
初始矩阵乘法运行耗时: 470.859915 ms
优化后矩阵乘法运行耗时: 143.617264 ms
加速比为:3.278575
yang@yang-virtual-machine:~/桌面/multiply$ ./multiply
初始矩阵乘法运行耗时: 441.426028 ms
优化后矩阵乘法运行耗时: 221.671424 ms
加速比为:1.991353
yang@yang-virtual-machine:~/桌面/multiply$ ./multiply
初始矩阵乘法运行耗时: 471.820829 ms
优化后矩阵乘法运行耗时: 143.121279 ms
加速比为:3.296650
yang@yang-virtual-machine:~/桌面/multiply$ ./multiply
初始矩阵乘法运行耗时: 472.508484 ms
优化后矩阵乘法运行耗时: 165.145991 ms
加速比为:2.861156
yang@yang-virtual-machine:~/桌面/multiply$ ./multiply
初始矩阵乘法运行耗时: 452.870419 ms
优化后矩阵乘法运行耗时: 142.621640 ms
加速比为:3.175328
yang@yang-virtual-machine:~/桌面/multiply$ ./multiply
初始矩阵乘法运行耗时: 418.838389 ms
优化后矩阵乘法运行耗时: 145.792686 ms
加速比为:2.872835
yang@yang-virtual-machine:~/桌面/multiply$ ./multiply
初始矩阵乘法运行耗时: 469.951841 ms
优化后矩阵乘法运行耗时: 142.652713 ms
加速比为:3.294377
yang@yang-virtual-machine:~/桌面/multiply$ ./multiply
初始矩阵乘法运行耗时: 471.253499 ms
优化后矩阵乘法运行耗时: 145.502747 ms
加速比为:3.238795

分块,可以达到3,但不太稳定(改变bsize及dynamic的size效果不好):

	int bsize=20;
	int i, j, k, kk, jj;
    double sum;
    int en = bsize * (N/bsize); 
 	#pragma omp parallel  shared(a,b,N,en,bsize) private(i,j,k,kk,jj,sum)
    for (kk = 0; kk < en; kk += bsize) { 
        for (jj = 0; jj < en; jj += bsize) {
        #pragma omp for schedule(dynamic,4)
            for (i = 0; i < N; i++) {
                for (j = jj; j < jj + bsize; j++) {
                    sum = c[i][j];
                    for (k = kk; k < kk + bsize; k++) {
                         sum += a[i][k]*b[k][j];
                    }
                    c[i][j] = sum;
                }
            }
        }
     }
yang@yang-virtual-machine:~/桌面/multiply$ ./multiply
初始矩阵乘法运行耗时: 478.490732 ms
优化后矩阵乘法运行耗时: 160.485123 ms
加速比为:2.981527
yang@yang-virtual-machine:~/桌面/multiply$ ./multiply
初始矩阵乘法运行耗时: 473.845689 ms
优化后矩阵乘法运行耗时: 197.628966 ms
加速比为:2.397653
yang@yang-virtual-machine:~/桌面/multiply$ ./multiply
初始矩阵乘法运行耗时: 472.802191 ms
优化后矩阵乘法运行耗时: 147.701017 ms
加速比为:3.201076
yang@yang-virtual-machine:~/桌面/multiply$ ./multiply
初始矩阵乘法运行耗时: 476.721597 ms
优化后矩阵乘法运行耗时: 149.472955 ms
加速比为:3.189350
yang@yang-virtual-machine:~/桌面/multiply$ ./multiply
初始矩阵乘法运行耗时: 267.305468 ms
优化后矩阵乘法运行耗时: 191.290913 ms
加速比为:1.397377
yang@yang-virtual-machine:~/桌面/multiply$ ./multiply
初始矩阵乘法运行耗时: 472.412870 ms
优化后矩阵乘法运行耗时: 162.142325 ms
加速比为:2.913569

2.稀疏矩阵向量乘

背景介绍: https://xupsh.github.io/pp4fpgas-cn/06-Sparse-Matrix-Vector-Multiplication.html

采用CSR存储格式: https://zhuanlan.zhihu.com/p/342942385
在这里插入图片描述

inline void smmSerial(const int numRows,const int *rowIndex,const int *columnIndex,const float *val,const float *x,float *r){
	int rowStart;
	int rowEnd;
    #pragma omp parallel for schedule(dynamic)
	for(int i=0;i<numRows;i++){
		rowStart=rowIndex[i];
		rowEnd=rowIndex[i+1];
		float sum=0.0f;
		for(int j=rowStart;j<rowEnd;j++){
			sum+=val[j]*x[columnIndex[j]];
		}
		r[i]=sum;
	}
}

题中的size应6

yang@yang-virtual-machine:~/桌面/openmp$ ./xsjz
r[0]=0.000000,r[1]=0.000000,r[2]=0.000000,r[3]=0.000000

r[0]=160.000000,r[1]=270.000000,r[2]=520.000000,r[3]=80.000000
size=5 运行50000次耗时: 44.921875 ms
r[0]=160.000000,r[1]=270.000000,r[2]=520.000000,r[3]=80.000000
size=6 运行50000次耗时: 41.015625 ms
r[0]=160.000000,r[1]=270.000000,r[2]=520.000000,r[3]=80.000000
size=3 运行50000次耗时: 54.687500 ms
r[0]=160.000000,r[1]=270.000000,r[2]=520.000000,r[3]=80.000000
size=4 运行50000次耗时: 48.828125 ms

测试代码:

#include<iostream>
#include<cstdlib>
#include<ctime>
#include<stdio.h>
#include<omp.h>
using namespace std;

inline void smmSerial(const int numRows,const int *rowIndex,const int *columnIndex,const float *val,const float *x,float *r){
	int rowStart;
	int rowEnd;
	for(int i=0;i<numRows;i++){
		rowStart=rowIndex[i];
		rowEnd=rowIndex[i+1];
		float sum=0.0f;
		for(int j=rowStart;j<rowEnd;j++){
			sum+=val[j]*x[columnIndex[j]];
		}
		r[i]=sum;
	}
}
inline void smmSerial1(const int numRows,const int *rowIndex,const int *columnIndex,const float *val,const float *x,float *r){
	int rowStart;
	int rowEnd;
    #pragma omp parallel for schedule(dynamic,1)
	for(int i=0;i<numRows;i++){
		rowStart=rowIndex[i];
		rowEnd=rowIndex[i+1];
		float sum=0.0f;
		for(int j=rowStart;j<rowEnd;j++){
			sum+=val[j]*x[columnIndex[j]];
		}
		r[i]=sum;
	}
}

inline void smmSerial2(const int numRows,const int *rowIndex,const int *columnIndex,const float *val,const float *x,float *r){
	int rowStart;
	int rowEnd;
    #pragma omp parallel for schedule(dynamic,2)
	for(int i=0;i<numRows;i++){
		rowStart=rowIndex[i];
		rowEnd=rowIndex[i+1];
		float sum=0.0f;
		for(int j=rowStart;j<rowEnd;j++){
			sum+=val[j]*x[columnIndex[j]];
		}
		r[i]=sum;
	}
}

inline void smmSerial3(const int numRows,const int *rowIndex,const int *columnIndex,const float *val,const float *x,float *r){
	int rowStart;
	int rowEnd;
    #pragma omp parallel for schedule(dynamic,4)
	for(int i=0;i<numRows;i++){
		rowStart=rowIndex[i];
		rowEnd=rowIndex[i+1];
		float sum=0.0f;
		for(int j=rowStart;j<rowEnd;j++){
			sum+=val[j]*x[columnIndex[j]];
		}
		r[i]=sum;
	}
}

inline void smmSerial4(const int numRows,const int *rowIndex,const int *columnIndex,const float *val,const float *x,float *r){
	int rowStart;
	int rowEnd;
    #pragma omp parallel for schedule(dynamic,8)
	for(int i=0;i<numRows;i++){
		rowStart=rowIndex[i];
		rowEnd=rowIndex[i+1];
		float sum=0.0f;
		for(int j=rowStart;j<rowEnd;j++){
			sum+=val[j]*x[columnIndex[j]];
		}
		r[i]=sum;
	}
}

int matrix_to_csr(int n, float **M,float* &val,int* & rowIndex,int* & columnIndex){
   int i,j;
   int a=0;
   for(i=0;i<n;i++)
      for(j=0;j<n;j++)
          if(M[i][j]!=0.0)
              a++;//a非零元素个数 
   val=new float[a];
   columnIndex=new int[a];
   rowIndex=new int[n+1];
   int k=0;
   int p=0;
   for(i=0;i<n;i++)
      for(j=0;j<n;j++){
          if(j==0)
              rowIndex[p++]=k;
          if(M[i][j]!=0.0){
              val[k]=M[i][j];
              columnIndex[k]=j;
              k++;}
   }
   rowIndex[p]=a;
   return a;//a非零元素个数 
}

void generate_sparse_matrix(float** & m,int n,double s){//s矩阵稀疏程度
   m=new float*[n];
   for(int i=0;i<n;i++)
       m[i]=new float[n];
   for(int i=0;i<n;i++)
      for(int j=0;j<n;j++)
      {
          int x=rand()%100000000;
          if(x>100000000*s)
            m[i][j]=0;
          else
            m[i][j]=(x+1)/1000000.0;
      }
   return;
}
void print_matrix(float **m,int n){
   for(int i=0;i<n;i++)
       for(int j=0;j<n;j++)
   {
           cout<<m[i][j]<<",";
           if(j==n-1)
               cout<<endl;
   }
   return;
}

void generate_vector(int n,float* & x){
    x=new float[n];
    for(int i=0;i<n;i++)
        x[i]=(rand()%100000000+1)/1000000.0;
    return;
}

void print_vector(int n,float* x){
    for(int i=0;i<n;i++)
        cout<<x[i]<<" ";
    return;
}

int main(){
    srand(time(0));
    int n;
    double s;
    cout<<"输入n:";
    cin>>n;
    cout<<"输入矩阵稀疏程度:";
    cin>>s;
    float **mat=NULL;
    float *x=NULL;
    float *r=NULL;
    float *val=NULL;
    int *columnindex=NULL;
    int *rowindex=NULL;
    generate_sparse_matrix(mat,n,s);
    
    /*print_matrix(mat,n);
    cout<<endl;
    cout<<endl;*/
    generate_vector(n,x);
    //print_vector(n,x);
    generate_vector(n,r);
    /*cout<<endl;
    cout<<endl;*/
    int a=matrix_to_csr(n,mat,val,rowindex,columnindex);
    
	float t0,t1,T0;
	t0 = omp_get_wtime();
	for(int i=0;i<100;i++){
		smmSerial(n,rowindex,columnindex,val,x,r);
	}
	t1 = omp_get_wtime();
	//print_vector(n,r);
	//cout<<endl;cout<<endl;
	T0 = (t1-t0)*1000;
	printf("初始运行100耗时: %f ms\n", T0);
	
	t0 = omp_get_wtime();
	for(int i=0;i<100;i++){
		smmSerial1(n,rowindex,columnindex,val,x,r);
	}
	t1 = omp_get_wtime();
	T0 = (t1-t0)*1000;
	printf("size=1 运行100耗时: %f ms\n", T0);
	
	t0 = omp_get_wtime();
	for(int i=0;i<100;i++){
		smmSerial2(n,rowindex,columnindex,val,x,r);
	}
	t1 = omp_get_wtime();
	T0 = (t1-t0)*1000;
	printf("size=2 运行100耗时: %f ms\n", T0);
	
	t0 = omp_get_wtime();
	for(int i=0;i<100;i++){
		smmSerial3(n,rowindex,columnindex,val,x,r);
	}
	t1 = omp_get_wtime();
	T0 = (t1-t0)*1000;
	printf("size=4 运行100耗时: %f ms\n", T0);
	
	t0 = omp_get_wtime();
	for(int i=0;i<100;i++){
		smmSerial4(n,rowindex,columnindex,val,x,r);
	}
	t1 = omp_get_wtime();
	T0 = (t1-t0)*1000;
	printf("size=8 运行100耗时: %f ms\n", T0);

    return 0;
}
#部分结果
yang@yang-virtual-machine:~/桌面/openmp$ g++ -fopenmp csjz.cpp -o csjz
yang@yang-virtual-machine:~/桌面/openmp$ ./csjz
输入n:500
输入矩阵稀疏程度:0.3
初始运行100耗时: 29.296875 ms
size=1 运行100耗时: 19.531250 ms
size=2 运行100耗时: 23.437500 ms
size=3 运行100耗时: 21.484375 ms
size=4 运行100耗时: 15.625000 ms
yang@yang-virtual-machine:~/桌面/openmp$ ./csjz
输入n:500
输入矩阵稀疏程度:0.3
初始运行100耗时: 31.250000 ms
size=1 运行100耗时: 21.484375 ms
size=2 运行100耗时: 19.531250 ms
size=3 运行100耗时: 21.484375 ms
size=4 运行100耗时: 23.437500 ms
yang@yang-virtual-machine:~/桌面/openmp$ ./csjz
输入n:500
输入矩阵稀疏程度:0.3
初始运行100耗时: 29.296875 ms
size=1 运行100耗时: 21.484375 ms
size=2 运行100耗时: 19.531250 ms
size=3 运行100耗时: 19.531250 ms
size=4 运行100耗时: 23.437500 ms

总结:可能是随机产生的矩阵不定因素有点多或者代码有问题,无法确定size的大小。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值