1、并行程序学习
(1)、对 ( ∑ i = 1 n 3 i 2 + 2 i ) \displaystyle \left(\sum_{i=1}^n 3i^2+2i \right) (i=1∑n3i2+2i)(n=1000),实现MPI并行版本,OpenMP并行版本
MPI版本 |
---|
一开始设计的时候只看了一节技术文档 , 后面的通信篇没有看懂 , 以为写上 MPI_Init(&argc, &argv); 和MPI_Finalize(); 并且指定运算的核心数目就可以并行运算了 , 但实际运行时运行结果出现了重复的情况 , 一个结果运行了与指定核心数相同的次数 , 一开始认为需要和OpenMP一样要指定制导指令 , 后来将MPI讲义文档 , 和各博主的博客多翻阅了几遍 , 才发现MPI需要进行通信来进行并行运算 , 在并行时需将数据划分成分行或者块来进行进程间的通信计算(参考矩阵的划分) |
OpenMp版本 |
---|
#include<stdio.h>
#include<math.h>
void add(){
long sum=0;
#pragma omp parallel for
for(int i=1; i<=1000; i++){
sum+=(long)3*pow(i,2)+2*i;
printf("i = %-5d,sum = %ld\n",i,sum);
}
}
int main(){
add();
return 0;
}
/**
*
* Author haopan
* History 2020.7.9
* i=(1-1000) 3*i^2+2*i
**/
(2)、实现二维数组乘的MPI并行版本,OpenMP并行版本
MPI |
---|
OpenMp |
---|
独立设计的算法 , 具体思路和百度到的文档算法基本相同 : 写三个for循环,第二个for循环来进行arr2数组的列变化以及重置 , 如下程序中的 mutil() 函数中的 嵌套的第二个for循环中的 r |
并行,随机生成0-100的数50*50的规模(指定8个线程执行):spend 0.001444seconds |
串行spend 0.001483seconds |
并行,随机生成0-100的数1000*1000的规模(指定8个线程执行):并行spend 6.350678seconds |
串行spend 9.550091seconds |
并行,随机生成0-100的数1000*1000的规模(指定8个线程执行):并行spend 6.350678seconds |
串行spend 9.550091seconds |
10000*10000的没有观测到运行结果 |
并行代码
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
//矩阵相乘,实际相乘的次数为行的3次幂,加的次数为行的2次幂
//int** arr 用于创建动态二位数组
void multi(int** arr1, int** arr2, int width){
int one_sum=0;
int sum = width*width;
int k=0;
int* mutil;
mutil = (int*)malloc(sizeof(int)*sum);
clock_t start_clock, end_clock;
start_clock = clock();
for(int i=0; i<width; i++){
//k主要是起到指向换列的作用,在计算出一个新的数值之后换列再计算下一个数值,换完所有列,重置为0
for(int r=0; r<width; r++){//r代表着b数组一个列循环完要循环下一个列了
#pragma omp parallel for num_threads(8)
for(int j=0; j<width; j++){
one_sum += arr1[i][j]*arr2[j][r];
//查看每一步one_sum即乘积的值
//printf("%d\n",one_sum);
}
mutil[k++] = one_sum;
one_sum = 0;
}
}
end_clock = clock();
for(int i=1; i<=sum; i++){
printf("%-10d",mutil[i-1]);
if(i%width == 0)
printf("\n");
}
printf("\nspend %fseconds\n",(double)(end_clock-start_clock)/CLOCKS_PER_SEC);
free(mutil);
}
int main(int argc, char **argv){
int** arr1;
int** arr2;
//m1 x n是一个二维数组,n x m2是一个二维数组
int width;
//输入你即将输入的第一个数组的大小
printf("please enter the width of matrix:\n");
scanf("%d",&width);
//先给申请行指针的地址空间
arr1 = (int**)malloc(sizeof(int*)*width*width);
arr2 = (int**)malloc(sizeof(int*)*width*width);
if(arr1 == NULL || arr2 == NULL)
return 0;
//初始化矩阵
srand((unsigned)time(NULL));
printf("第一个矩阵\n");
for(int i=0; i<width; i++){
arr1[i] = (int*)malloc(sizeof(int)*width);
for(int j=0; j<width; j++){
arr1[i][j] = rand()%100;
printf("%-3d ",arr1[i][j]);
}
printf("\n");
}
printf("第二个矩阵\n");
for(int i=0; i<width; i++){
arr2[i] = (int*)malloc(sizeof(int)*width);
for(int j=0; j<width; j++){
arr2[i][j] = rand()%100;
printf("%-3d ",arr2[i][j]);
}
printf("\n");
}
multi(arr1, arr2, width);
free(arr1);
free(arr2);
return 0;
}
/**
*创建矩阵的相乘,二维数组相乘的话需要补空位为0,或者写个初始化的函数
*
*Author haopan
*Hitory 2020.7.10
*
*/
串行代码
```c
去掉上面代码的
#pragma omp parallel for num_threads(8)
【对上述两种并行方式,写一份报告,提供源码;编译、运行脚本;设计思路、对不同运算规模、不同并行规模进行分析;结论等】
(3)、尝试实现C、Fortran语言高斯消元解方程组的MPI、OpenMP版本
还没有开始 |
---|
(4)、学习过程记录(未整理)
一Linux环境下的OpenMP多线程编程
https://blog.csdn.net/qq_20198487/article/details/51626464
gcc -fopenmp filename.c -o filename
@qq_20198487
二add.c:17:1: error: unterminated comment 注释未终止
i = 1 ,sum = 5
i = 2 ,sum = 21
i = 3 ,sum = 54
i = 4 ,sum = 110
i = 5 ,sum = 195
i = 6 ,sum = 315
i = 7 ,sum = 476
i = 8 ,sum = 684
i = 9 ,sum = 945
i = 10 ,sum = 1265
i = 11 ,sum = 1650
i = 12 ,sum = 2106
i = 13 ,sum = 2639
i = 14 ,sum = 3255
i = 15 ,sum = 3960
i = 16 ,sum = 4760
i = 17 ,sum = 5661
i = 18 ,sum = 6669
i = 19 ,sum = 7790
i = 20 ,sum = 9030
i = 21 ,sum = 10395
i = 22 ,sum = 11891
i = 23 ,sum = 13524
i = 24 ,sum = 15300
i = 25 ,sum = 17225
i = 26 ,sum = 19305
i = 27 ,sum = 21546
i = 28 ,sum = 23954
i = 29 ,sum = 26535
i = 30 ,sum = 29295
i = 31 ,sum = 32240
i = 32 ,sum = 35376
i = 33 ,sum = 38709
i = 34 ,sum = 42245
i = 35 ,sum = 45990
i = 36 ,sum = 49950
i = 37 ,sum = 54131
i = 38 ,sum = 58539
i = 39 ,sum = 63180
i = 40 ,sum = 68060
i = 41 ,sum = 73185
i = 42 ,sum = 78561
i = 43 ,sum = 84194
i = 1 ,sum = 5
i = 2 ,sum = 21
i = 1 ,sum = 5
i = 2 ,sum = 21
i = 3 ,sum = 54
i = 4 ,sum = 110
i = 5 ,sum = 195
出现重复运行
三linux编译出现undefined reference to `pow‘的错误
因为默认没有math.h库
https://blog.csdn.net/u010597161/article/details/18551507
@放晴的时候
四
i = 1 ,sum = 4470150
i = 2 ,sum = 182006624
i = 3 ,sum = 182006657
i = 4 ,sum = 182006713
i = 5 ,sum = 182006798
i = 146 ,sum = 170408173
i = 147 ,sum = 182072039
i = 148 ,sum = 182138047
i = 149 ,sum = 182204948
i = 150 ,sum = 182272748
i = 151 ,sum = 182341453
i = 152 ,sum = 182411069
i = 153 ,sum = 182481602
运行累加计算式的时候出现问题,不能对for循环中有两个数在for循环上方#pagma mop parallel for
打包成函数,调用函数对函数指定线程进行并行运算
五 英语
clause从句; 分句; 子句; 条款
19/100
发布文章

加粗
斜体
标题
删除线
无序
有序
待办
引用
代码块
图片
视频
表格
超链接
摘要
Choose File
导入
导出
保存
撤销
重做
目录
帮助
1、并行程序学习
(1)、对 ( ∑ i = 1 n 3 i 2 + 2 i ) \displaystyle \left(\sum_{i=1}^n 3i^2+2i \right) (i=1∑n3i2+2i)(n=1000),实现MPI并行版本,OpenMP并行版本
MPI版本 |
---|
一开始设计的时候只看了一节技术文档 , 后面的通信篇没有看懂 , 以为写上 MPI_Init(&argc, &argv); 和MPI_Finalize(); 并且指定运算的核心数目就可以并行运算了 , 但实际运行时运行结果出现了重复的情况 , 一个结果运行了与指定核心数相同的次数 , 一开始认为需要和OpenMP一样要指定制导指令 , 后来将MPI讲义文档 , 和各博主的博客多翻阅了几遍 , 才发现MPI需要进行通信来进行并行运算 , 在并行时需将数据划分成分行或者块来进行进程间的通信计算(参考矩阵的划分) |
OpenMp版本 |
---|
#include<stdio.h>
#include<math.h>
void add(){
long sum=0;
#pragma omp parallel for
for(int i=1; i<=1000; i++){
sum+=(long)3*pow(i,2)+2*i;
printf("i = %-5d,sum = %ld\n",i,sum);
}
}
int main(){
add();
return 0;
}
/**
*
* Author haopan
* History 2020.7.9
* i=(1-1000) 3*i^2+2*i
**/
(2)、实现二维数组乘的MPI并行版本,OpenMP并行版本
MPI |
---|
OpenMp |
---|
独立设计的算法 , 具体思路和百度到的文档算法基本相同 : 写三个for循环,第二个for循环来进行arr2数组的列变化以及重置 , 如下程序中的 mutil() 函数中的 嵌套的第二个for循环中的 r |
并行,随机生成0-100的数50*50的规模(指定8个线程执行):spend 0.001444seconds |
串行spend 0.001483seconds |
并行代码
#include<stdio.h>
#include<stdlib.h>
//矩阵相乘,实际相乘的次数为行的3次幂,加的次数为行的2次幂
//int** arr 用于创建动态二位数组
multi(int** arr1, int** arr2, int m1, int n, int m2){
int one_sum=0;
int sum = m1*m2;
int k=0;
int* mutil;
mutil = (int*)malloc(sizeof(int)*sum);
#pragma omp parallel for num_threads(8)
for(int i=0; i<m1; i++){
//r主要是起到指向换列的作用,在计算出一个新的数值之后换列再计算下一个数值,换完所有列,重置为0
for(int r=0; r<m2; r++){//r代表着b数组一个列循环完要循环下一个列了
for(int j=0; j<n; j++){
one_sum += arr1[i][j]*arr2[j][r];
//查看每一步one_sum即乘积的值
//printf("%d\n",one_sum);
}
printf("%-5d (thread_id: %-6d) ", one_sum, omp_get_thread_num());
mutil[k++] = one_sum;
one_sum = 0;
}
printf("\n");
}
free(mutil);
}
int main(int argc, char **argv){
int** arr1;
int** arr2;
//m1 x n是一个二维数组,n x m2是一个二维数组
int m1=0,n=0,m2=0,n1;
//输入你即将输入的第一个数组的大小
printf("please enter the size of first 2D array : m n\n");
scanf("%d%d",&m1,&n);
//先给申请行指针的地址空间
arr1 = (int**)malloc(sizeof(int*)*m1);
for(int i=0; i<m1; i++){
//为每一行申请n个地址空间
arr1[i] = (int*)malloc(sizeof(int)*n);
//判断函数返回值是否为0
if(arr1[i] == NULL) return 0;
for(int j=0; j<n; j++){
scanf("%d",&arr1[i][j]);
}
}
//输入你即将输入的第二个数组的大小
printf("please enter the size of second 2D array : m n\n");
scanf("%d%d",&n1,&m2);
arr2 = (int**)malloc(sizeof(int*)*n1);
//判断函数返回值是否为0
if(arr1 == NULL || arr2 == NULL)
return 0;
for(int i=0; i<n1; i++){
//为每一行申请n个地址空间
arr2[i] = (int*)malloc(sizeof(int)*m2);
//判断函数返回值是否为0
if(arr2[i] == NULL) return 0;
for(int j=0; j<m2; j++){
scanf("%d", &arr2[i][j]);
}
}
multi(arr1, arr2, m1, n, m2);
free(arr1);
free(arr2);
return 0;
}
/**
*创建矩阵的相乘,二维数组相乘的话需要补空位为0,或者写个初始化的函数
*
*Author haopan
*Hitory 2020.7.10
*
*/
串行代码
去掉上面代码的
#pragma omp parallel for num_threads(8)
【对上述两种并行方式,写一份报告,提供源码;编译、运行脚本;设计思路、对不同运算规模、不同并行规模进行分析;结论等】
(3)、尝试实现C、Fortran语言高斯消元解方程组的MPI、OpenMP版本
还没有开始 |
---|
(4)、学习过程记录(未整理)
一Linux环境下的OpenMP多线程编程
https://blog.csdn.net/qq_20198487/article/details/51626464
gcc -fopenmp filename.c -o filename
@qq_20198487
二add.c:17:1: error: unterminated comment 注释未终止
i = 1 ,sum = 5
i = 2 ,sum = 21
i = 3 ,sum = 54
i = 4 ,sum = 110
i = 5 ,sum = 195
i = 6 ,sum = 315
i = 7 ,sum = 476
i = 8 ,sum = 684
i = 9 ,sum = 945
i = 10 ,sum = 1265
i = 11 ,sum = 1650
i = 12 ,sum = 2106
i = 13 ,sum = 2639
i = 14 ,sum = 3255
i = 15 ,sum = 3960
i = 16 ,sum = 4760
i = 17 ,sum = 5661
i = 18 ,sum = 6669
i = 19 ,sum = 7790
i = 20 ,sum = 9030
i = 21 ,sum = 10395
i = 22 ,sum = 11891
i = 23 ,sum = 13524
i = 24 ,sum = 15300
i = 25 ,sum = 17225
i = 26 ,sum = 19305
i = 27 ,sum = 21546
i = 28 ,sum = 23954
i = 29 ,sum = 26535
i = 30 ,sum = 29295
i = 31 ,sum = 32240
i = 32 ,sum = 35376
i = 33 ,sum = 38709
i = 34 ,sum = 42245
i = 35 ,sum = 45990
i = 36 ,sum = 49950
i = 37 ,sum = 54131
i = 38 ,sum = 58539
i = 39 ,sum = 63180
i = 40 ,sum = 68060
i = 41 ,sum = 73185
i = 42 ,sum = 78561
i = 43 ,sum = 84194
i = 1 ,sum = 5
i = 2 ,sum = 21
i = 1 ,sum = 5
i = 2 ,sum = 21
i = 3 ,sum = 54
i = 4 ,sum = 110
i = 5 ,sum = 195
出现重复运行
三linux编译出现undefined reference to `pow‘的错误
因为默认没有math.h库
https://blog.csdn.net/u010597161/article/details/18551507
@放晴的时候
四
i = 1 ,sum = 4470150
i = 2 ,sum = 182006624
i = 3 ,sum = 182006657
i = 4 ,sum = 182006713
i = 5 ,sum = 182006798
i = 146 ,sum = 170408173
i = 147 ,sum = 182072039
i = 148 ,sum = 182138047
i = 149 ,sum = 182204948
i = 150 ,sum = 182272748
i = 151 ,sum = 182341453
i = 152 ,sum = 182411069
i = 153 ,sum = 182481602
运行累加计算式的时候出现问题,不能对for循环中有两个数在for循环上方#pagma mop parallel for
打包成函数,调用函数对函数指定线程进行并行运算
五 英语
clause从句; 分句; 子句; 条款
expected ‘#pragma omp’ clause before ‘{’ token
“{”标记前应有“#pragma omp”子句
六 MPI相关
apt-get update“从源服务器下载最新的软件包列表。
从源服务器下载最新的软件包列表。
sudo apt-get install -y 同意安装过程的所有信息
语言 C C++ Fortran 77 Fortran 90
编译器 gcc g++ gfortran gfortran
MPI编译器 mpicc mpic++/mpicxx/mpiCC mpif77 mpif90
2.1 MPI程序的编译
利用 mpicc 命令编译MPI代码文件。mpicc 是编译并链接用C编写的MPI程序的命令。
mpicc mpi.c -o mpi.o
2.2 MPI程序的运行
利用 mpirun 命令运行程序。其中 -np 选项指定处理器数目。mpirun 是MPI程序的启动脚本,它可以简化作业的启动程序,并且尽可能把不同特征屏蔽掉,提供给用户一个通用的MPI并行机的概念。
mpirun -np 8 ./mpi.o
mpicc loop_add.c -lm -o loop_add -lm调用math.h库 mpicc是编译程序
mpirun -np 8 ./loop_add 指定8个线程运行
i = 1 ,sum = 5
i = 2 ,sum = 21
i = 3 ,sum = 54
i = 4 ,sum = 110
i = 5 ,sum = 195
i = 6 ,sum = 315
i = 7 ,sum = 476
i = 8 ,sum = 684
i = 9 ,sum = 945
i = 10 ,sum = 1265
i = 11 ,sum = 1650
i = 12 ,sum = 2106
i = 13 ,sum = 2639
i = 14 ,sum = 3255
i = 15 ,sum = 3960
i = 16 ,sum = 4760
i = 17 ,sum = 5661
i = 1 ,sum = 5
i = 2 ,sum = 21
i = 3 ,sum = 54
i = 4 ,sum = 110
i = 5 ,sum = 195
i = 6 ,sum = 315
i = 7 ,sum = 476
i = 8 ,sum = 684
i = 9 ,sum = 945
i = 10 ,sum = 1265
i = 11 ,sum = 1650
i = 12 ,sum = 2106
i = 13 ,sum = 2639
i = 14 ,sum = 3255
出现重复运行
mpirun -np 1 ./loop_add
指定一个进程来进行运算就不会重复,这个数字是指多个进程来多个程序,不是运行一个程序吗?
在写矩阵函数的时候出现的问题
(多写了一个h,本来是想的能够将b矩阵计算完一轮后列能够重新指向第一列,不能用外层循环的i当做列的动态索引,所以舍弃i自己再写一个索引.
但是我函数中b矩阵本来就没有用到i当索引,不也不会出现)
(图片中的情况)
//矩阵相乘,实际相乘的次数为行的3次幂,加的次数为行的2次幂
void multi(int (*a)[3], int (*b)[3]){
int one_sum=0;
int mutil[9] = {0};
int c[3][3]={0};
int h=0,k=0,n=0;
for(int i=0; i<3; i++){
//h主要是起到指向换行的作用,在一行数计算完成后换行,计算下一行的数值,换完所有行,重置为0
//k主要是起到指向换列的作用,在计算出一个新的数值之后换列再计算下一个数值,换完所有列,重置为0
for(int r=0; r<3; r++){//r代表着b数组一个列循环完要循环下一个列了
for(int j=0; j<3; j++){
one_sum += a[i][j]*b[j][h+k];
//查看每一步one_sum即乘积的值
printf("%d\n",one_sum);
}
mutil[n++] = one_sum;
one_sum = 0;
k++;
}
k=0;
h++;
}
for(int i=0; i<9; i++){
printf("%d “,mutil[i]);
if(i%3==0){
printf(”\n");
}
}
}
Linux 下搜狗输入法崩溃
秩就是,矩阵A中非零子式的最高阶数,称为矩阵A的秩,记作r(A)
https://zhidao.baidu.com/question/41250067.html
累加的设计思路好说
而二维数组相乘的设计思路,还要牵扯到动态改变数组大小.考虑不同的运算规模的事情该是怎样的,对不同的运算规模进行分析,还要写结论
七 讲述如何申请动态内存的
https://blog.csdn.net/qq_41071068/article/details/90741413
包括了静态内存的,malloc calloc,free函数各自的使用方式和相互关系.
/malloc函数在stdlib.h里面,用的时候加入这个头文件/
int ** a;
int m,n,i;
scanf("%d%d",&m,&n);
a=(int**)malloc(msizeof(int)); /malloc函数在stdlib.h里面,用的时候加入这个头文件/
for(i=0;i<m;i++)
a[i]=(int*)malloc(n*sizeof(int));
原文链接:https://blog.csdn.net/welcomeu/article/details/13094865
动态二维数组做形参:https://blog.csdn.net/jk_chen_acmer/article/details/80297411
Segmentation fault (core dumped)错误的引用没有赋值的地址就会报错
为了使程序能够符合矩阵相乘第一个的列必须和第二个行相等的条件,我两次scanf都要求输入了n,其实不好的
C语言中经常遇到的 segmentation fault 错误
https://blog.csdn.net/lds_lsj/article/details/48199101
直接拷贝(只需要换变量的)重复的代码也是需要加强注意力的,牢记它的表征,正确的方式只有把注意力集中到需要换置的位置.
printf(“please enter the size of first 2D array : m n\n”);
scanf("%d%d",&m1,&n);
//先给申请行指针的地址空间
arr1 = (int**)malloc(sizeof(int*)*m1);
for(int i=0; i<m1; i++){
//为每一行申请n个地址空间
arr1[i] = (int*)malloc(sizeof(int)*n);
//判断函数返回值是否为0
if(arr1[i] == NULL) return 0;
for(int j=0; j<n; j++){
scanf("%d",&arr1[i][j]);
}
}
for(int i=0; i<m1; i++)
for(int j=0; j<n; j++)
printf("%d ",arr1[i][j]);
//输入你即将输入的第二个数组的大小
printf("please enter the size of second 2D array : m n\n");
scanf("%d%d",&n1,&m2);
arr2 = (int**)malloc(sizeof(int*)*n2);
//判断函数返回值是否为0
if(arr1 == NULL || arr2 == NULL)
return 0;
for(int i=0; i<n1; i++){
//为每一行申请n个地址空间
arr1[i] = (int*)malloc(sizeof(int)*m2);
//判断函数返回值是否为0
if(arr1[i] == NULL) return 0;
for(int j=0; j<m2; j++){
scanf("%d", &arr2[i][j]);
}
}
for(int i=0; i<n; i++)
for(int j=0; j<m2; j++)
printf("%d ",arr2[i][j]);
吃了大亏.浪废了很多时间去排除错误.
在运行代码时我可以肯定逻辑没有错,但是重复的代码一个可以运行,一个不可以.所以我肯定有细节出现了问题.就那么几行代码,看了半天没看出来.我休息了一下,然后再看果然发现了问题.
如果你是得道的大侠,这篇文章可能浪费你的时间,如果你坚持要看,我当然感觉很高
兴,但是希望你看完了别骂我!如果你发现我这篇文章有错误的话,你可以提出批评以及
指正,我将很乐意地接受。_
看了老铁对二维数组的认识,觉得自己有必要在实践完后系统的整理一下知识.
https://bbs.csdn.net/topics/60157289
并行计算相关知识:
任务分担需要制导指令.
当使用 parellel 制导指令产生出并行域之后,如果仅仅是多个线程执行完全相同的任务,那么只是徒增计算工作量而不能达到加速计算的目的,甚至可能相互干扰得出错误结果。
1.void main(int argc, char *argv[]) {
2. #pragma omp parallel
3. { 并行域的开始 (对应 fork)
4. printf(“Hello, World!\n”);
5. } 并行域的结束(对应 join)
6.}
OpenMP可以完成的任务分担的指令只有for、sections和single,严格意义上来说只有 for 和 sections 是任务分担指令,而 single 只是协助任务分担的指
讲的很详细
5. MPI_Send(buf,counter,datatype,dest,tag,comm)
buf:发送缓冲区的起始地址,可以是数组或结构指针;
count:非负整数,发送的数据个数;
datatype:发送数据的数据类型;
dest:整型,目的的进程号;
tag:整型,消息标志;comm:MPI进程组所在的通信域
含义:向通信域中的dest进程发送数据,数据存放在buf中,类型
————————————————
版权声明:本文为CSDN博主「木东居士」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/zhaodedong/article/details/73441318
4.mpi 矩阵相乘
接下来便开始我们的主题
实际的思想是使用0进程将矩阵切分成n份分别发送个其他的进程,再有其他的进程计算完成之后再发回0进程。
0进程进行分发,切分,以及整合矩阵。
MPI部分,先是学习的入门文档,当时惯性认为和OpenMp是一样的,指定制导指令就可以对那部分代码进行并行计算.事实是我没有将MPI 的核心弄明白.就先入为主去'做'了.结果就是怎么翻文档都找不到所谓的制导指令.然后认真将MPI 看了一遍,入了个门知道MPI是怎么回事了,MPI是通过进程间通信发送,接收来实现并行的.
MPI的实例参考,主要是二维数组的划分以及二维数组计算的通信过程
https://www.docin.com/p-639862237.html
实例参考,真正的实例
https://blog.csdn.net/qq_41311396/article/details/90297427?utm_medium=distribute.pc_relevant.none-task-blog-baidujs-1
生成随机数的讲解
https://zhidao.baidu.com/question/431958534517233884.html
MPI计算二维数组的(讲的最详细的,思路很清晰)
https://www.cnblogs.com/Romi/archive/2012/07/13/2588412.html






SecondWeek
1、并行程序学习
(1)、对\displaystyle \left(\sum_{i=1}^n 3i^2+2i \right)(
i=1
∑
n
3i
2
+2i)(n=1000),实现MPI并行版本,OpenMP并行版本
(2)、实现二维数组乘的MPI并行版本,OpenMP并行版本
【对上述两种并行方式,写一份报告,提供源码;编译、运行脚本;设计思路、对不同运算规模、不同并行规模进行分析;结论等】
(3)、尝试实现C、Fortran语言高斯消元解方程组的MPI、OpenMP版本
(4)、学习过程记录(未整理)
1、并行程序学习
(1)、对\displaystyle \left(\sum_{i=1}^n 3i^2+2i \right)(
i=1
∑
n
3i
2
+2i)(n=1000),实现MPI并行版本,OpenMP并行版本
MPI版本
一开始设计的时候只看了一节技术文档 , 后面的通信篇没有看懂 , 以为写上 MPI_Init(&argc, &argv); 和MPI_Finalize(); 并且指定运算的核心数目就可以并行运算了 , 但实际运行时运行结果出现了重复的情况 , 一个结果运行了与指定核心数相同的次数 , 一开始认为需要和OpenMP一样要指定制导指令 , 后来将MPI讲义文档 , 和各博主的博客多翻阅了几遍 , 才发现MPI需要进行通信来进行并行运算 , 在并行时需将数据划分成分行或者块来进行进程间的通信计算(参考矩阵的划分)
OpenMp版本
#include<stdio.h>
#include<math.h>
void add(){
long sum=0;
#pragma omp parallel for
for(int i=1; i<=1000; i++){
sum+=(long)3pow(i,2)+2i;
printf(“i = %-5d,sum = %ld\n”,i,sum);
}
}
int main(){
add();
return 0;
}
/**
*
* Author haopan
* History 2020.7.9
- i=(1-1000) 3i^2+2i
**/
(2)、实现二维数组乘的MPI并行版本,OpenMP并行版本
MPI
OpenMp
独立设计的算法 , 具体思路和百度到的文档算法基本相同 : 写三个for循环,第二个for循环来进行arr2数组的列变化以及重置 , 如下程序中的 mutil() 函数中的 嵌套的第二个for循环中的 r
并行,随机生成0-100的数50*50的规模(指定8个线程执行):spend 0.001444seconds
串行spend 0.001483seconds
并行代码
#include<stdio.h>
#include<stdlib.h>
//矩阵相乘,实际相乘的次数为行的3次幂,加的次数为行的2次幂
//int** arr 用于创建动态二位数组
multi(int** arr1, int** arr2, int m1, int n, int m2){
int one_sum=0;
int sum = m1m2;
int k=0;
int mutil;
mutil = (int*)malloc(sizeof(int)*sum);
#pragma omp parallel for num_threads(8)
for(int i=0; i<m1; i++){
//r主要是起到指向换列的作用,在计算出一个新的数值之后换列再计算下一个数值,换完所有列,重置为0
for(int r=0; r<m2; r++){//r代表着b数组一个列循环完要循环下一个列了
for(int j=0; j<n; j++){
one_sum += arr1[i][j]*arr2[j][r];
//查看每一步one_sum即乘积的值
//printf("%d\n",one_sum);
}
printf("%-5d (thread_id: %-6d) ", one_sum, omp_get_thread_num());
mutil[k++] = one_sum;
one_sum = 0;
}
printf("\n");
}
free(mutil);
}
int main(int argc, char argv){
int arr1;
int** arr2;
//m1 x n是一个二维数组,n x m2是一个二维数组
int m1=0,n=0,m2=0,n1;
//输入你即将输入的第一个数组的大小
printf(“please enter the size of first 2D array : m n\n”);
scanf("%d%d",&m1,&n);
//先给申请行指针的地址空间
arr1 = (int**)malloc(sizeof(int*)*m1);
for(int i=0; i<m1; i++){
//为每一行申请n个地址空间
arr1[i] = (int*)malloc(sizeof(int)*n);
//判断函数返回值是否为0
if(arr1[i] == NULL) return 0;
for(int j=0; j<n; j++){
scanf("%d",&arr1[i][j]);
}
}
//输入你即将输入的第二个数组的大小
printf("please enter the size of second 2D array : m n\n");
scanf("%d%d",&n1,&m2);
arr2 = (int**)malloc(sizeof(int*)*n1);
//判断函数返回值是否为0
if(arr1 == NULL || arr2 == NULL)
return 0;
for(int i=0; i<n1; i++){
//为每一行申请n个地址空间
arr2[i] = (int*)malloc(sizeof(int)*m2);
//判断函数返回值是否为0
if(arr2[i] == NULL) return 0;
for(int j=0; j<m2; j++){
scanf("%d", &arr2[i][j]);
}
}
multi(arr1, arr2, m1, n, m2);
free(arr1);
free(arr2);
return 0;
}
/**
*创建矩阵的相乘,二维数组相乘的话需要补空位为0,或者写个初始化的函数
*
*Author haopan
*Hitory 2020.7.10
*
*/
串行代码
去掉上面代码的
#pragma omp parallel for num_threads(8)
【对上述两种并行方式,写一份报告,提供源码;编译、运行脚本;设计思路、对不同运算规模、不同并行规模进行分析;结论等】
(3)、尝试实现C、Fortran语言高斯消元解方程组的MPI、OpenMP版本
还没有开始
(4)、学习过程记录(未整理)
一Linux环境下的OpenMP多线程编程
https://blog.csdn.net/qq_20198487/article/details/51626464
gcc -fopenmp filename.c -o filename
@qq_20198487
二add.c:17:1: error: unterminated comment 注释未终止
i = 1 ,sum = 5
i = 2 ,sum = 21
i = 3 ,sum = 54
i = 4 ,sum = 110
i = 5 ,sum = 195
i = 6 ,sum = 315
i = 7 ,sum = 476
i = 8 ,sum = 684
i = 9 ,sum = 945
i = 10 ,sum = 1265
i = 11 ,sum = 1650
i = 12 ,sum = 2106
i = 13 ,sum = 2639
i = 14 ,sum = 3255
i = 15 ,sum = 3960
i = 16 ,sum = 4760
i = 17 ,sum = 5661
i = 18 ,sum = 6669
i = 19 ,sum = 7790
i = 20 ,sum = 9030
i = 21 ,sum = 10395
i = 22 ,sum = 11891
i = 23 ,sum = 13524
i = 24 ,sum = 15300
i = 25 ,sum = 17225
i = 26 ,sum = 19305
i = 27 ,sum = 21546
i = 28 ,sum = 23954
i = 29 ,sum = 26535
i = 30 ,sum = 29295
i = 31 ,sum = 32240
i = 32 ,sum = 35376
i = 33 ,sum = 38709
i = 34 ,sum = 42245
i = 35 ,sum = 45990
i = 36 ,sum = 49950
i = 37 ,sum = 54131
i = 38 ,sum = 58539
i = 39 ,sum = 63180
i = 40 ,sum = 68060
i = 41 ,sum = 73185
i = 42 ,sum = 78561
i = 43 ,sum = 84194
i = 1 ,sum = 5
i = 2 ,sum = 21
i = 1 ,sum = 5
i = 2 ,sum = 21
i = 3 ,sum = 54
i = 4 ,sum = 110
i = 5 ,sum = 195
出现重复运行
三linux编译出现undefined reference to `pow‘的错误
因为默认没有math.h库
https://blog.csdn.net/u010597161/article/details/18551507
@放晴的时候
四
i = 1 ,sum = 4470150
i = 2 ,sum = 182006624
i = 3 ,sum = 182006657
i = 4 ,sum = 182006713
i = 5 ,sum = 182006798
i = 146 ,sum = 170408173
i = 147 ,sum = 182072039
i = 148 ,sum = 182138047
i = 149 ,sum = 182204948
i = 150 ,sum = 182272748
i = 151 ,sum = 182341453
i = 152 ,sum = 182411069
i = 153 ,sum = 182481602
运行累加计算式的时候出现问题,不能对for循环中有两个数在for循环上方#pagma mop parallel for
打包成函数,调用函数对函数指定线程进行并行运算
五 英语
clause从句; 分句; 子句; 条款
expected ‘#pragma omp’ clause before ‘{’ token
“{”标记前应有“#pragma omp”子句
六 MPI相关
apt-get update“从源服务器下载最新的软件包列表。
从源服务器下载最新的软件包列表。
sudo apt-get install -y 同意安装过程的所有信息
语言 C C++ Fortran 77 Fortran 90
编译器 gcc g++ gfortran gfortran
MPI编译器 mpicc mpic++/mpicxx/mpiCC mpif77 mpif90
2.1 MPI程序的编译
利用 mpicc 命令编译MPI代码文件。mpicc 是编译并链接用C编写的MPI程序的命令。
mpicc mpi.c -o mpi.o
2.2 MPI程序的运行
利用 mpirun 命令运行程序。其中 -np 选项指定处理器数目。mpirun 是MPI程序的启动脚本,它可以简化作业的启动程序,并且尽可能把不同特征屏蔽掉,提供给用户一个通用的MPI并行机的概念。
mpirun -np 8 ./mpi.o
mpicc loop_add.c -lm -o loop_add -lm调用math.h库 mpicc是编译程序
mpirun -np 8 ./loop_add 指定8个线程运行
i = 1 ,sum = 5
i = 2 ,sum = 21
i = 3 ,sum = 54
i = 4 ,sum = 110
i = 5 ,sum = 195
i = 6 ,sum = 315
i = 7 ,sum = 476
i = 8 ,sum = 684
i = 9 ,sum = 945
i = 10 ,sum = 1265
i = 11 ,sum = 1650
i = 12 ,sum = 2106
i = 13 ,sum = 2639
i = 14 ,sum = 3255
i = 15 ,sum = 3960
i = 16 ,sum = 4760
i = 17 ,sum = 5661
i = 1 ,sum = 5
i = 2 ,sum = 21
i = 3 ,sum = 54
i = 4 ,sum = 110
i = 5 ,sum = 195
i = 6 ,sum = 315
i = 7 ,sum = 476
i = 8 ,sum = 684
i = 9 ,sum = 945
i = 10 ,sum = 1265
i = 11 ,sum = 1650
i = 12 ,sum = 2106
i = 13 ,sum = 2639
i = 14 ,sum = 3255
出现重复运行
mpirun -np 1 ./loop_add
指定一个进程来进行运算就不会重复,这个数字是指多个进程来多个程序,不是运行一个程序吗?
在写矩阵函数的时候出现的问题
(多写了一个h,本来是想的能够将b矩阵计算完一轮后列能够重新指向第一列,不能用外层循环的i当做列的动态索引,所以舍弃i自己再写一个索引.
但是我函数中b矩阵本来就没有用到i当索引,不也不会出现)
(图片中的情况)
//矩阵相乘,实际相乘的次数为行的3次幂,加的次数为行的2次幂
void multi(int (*a)[3], int (*b)[3]){
int one_sum=0;
int mutil[9] = {0};
int c[3][3]={0};
int h=0,k=0,n=0;
for(int i=0; i<3; i++){
//h主要是起到指向换行的作用,在一行数计算完成后换行,计算下一行的数值,换完所有行,重置为0
//k主要是起到指向换列的作用,在计算出一个新的数值之后换列再计算下一个数值,换完所有列,重置为0
for(int r=0; r<3; r++){//r代表着b数组一个列循环完要循环下一个列了
for(int j=0; j<3; j++){
one_sum += a[i][j]*b[j][h+k];
//查看每一步one_sum即乘积的值
printf("%d\n",one_sum);
}
mutil[n++] = one_sum;
one_sum = 0;
k++;
}
k=0;
h++;
}
for(int i=0; i<9; i++){
printf("%d “,mutil[i]);
if(i%3==0){
printf(”\n");
}
}
}
Linux 下搜狗输入法崩溃
秩就是,矩阵A中非零子式的最高阶数,称为矩阵A的秩,记作r(A)
https://zhidao.baidu.com/question/41250067.html
累加的设计思路好说
而二维数组相乘的设计思路,还要牵扯到动态改变数组大小.考虑不同的运算规模的事情该是怎样的,对不同的运算规模进行分析,还要写结论
七 讲述如何申请动态内存的
https://blog.csdn.net/qq_41071068/article/details/90741413
包括了静态内存的,malloc calloc,free函数各自的使用方式和相互关系.
/malloc函数在stdlib.h里面,用的时候加入这个头文件/
int ** a;
int m,n,i;
scanf("%d%d",&m,&n);
a=(int**)malloc(msizeof(int)); /malloc函数在stdlib.h里面,用的时候加入这个头文件/
for(i=0;i<m;i++)
a[i]=(int*)malloc(n*sizeof(int));
原文链接:https://blog.csdn.net/welcomeu/article/details/13094865
动态二维数组做形参:https://blog.csdn.net/jk_chen_acmer/article/details/80297411
Segmentation fault (core dumped)错误的引用没有赋值的地址就会报错
为了使程序能够符合矩阵相乘第一个的列必须和第二个行相等的条件,我两次scanf都要求输入了n,其实不好的
C语言中经常遇到的 segmentation fault 错误
https://blog.csdn.net/lds_lsj/article/details/48199101
直接拷贝(只需要换变量的)重复的代码也是需要加强注意力的,牢记它的表征,正确的方式只有把注意力集中到需要换置的位置.
printf(“please enter the size of first 2D array : m n\n”);
scanf("%d%d",&m1,&n);
//先给申请行指针的地址空间
arr1 = (int**)malloc(sizeof(int*)*m1);
for(int i=0; i<m1; i++){
//为每一行申请n个地址空间
arr1[i] = (int*)malloc(sizeof(int)*n);
//判断函数返回值是否为0
if(arr1[i] == NULL) return 0;
for(int j=0; j<n; j++){
scanf("%d",&arr1[i][j]);
}
}
for(int i=0; i<m1; i++)
for(int j=0; j<n; j++)
printf("%d ",arr1[i][j]);
//输入你即将输入的第二个数组的大小
printf("please enter the size of second 2D array : m n\n");
scanf("%d%d",&n1,&m2);
arr2 = (int**)malloc(sizeof(int*)*n2);
//判断函数返回值是否为0
if(arr1 == NULL || arr2 == NULL)
return 0;
for(int i=0; i<n1; i++){
//为每一行申请n个地址空间
arr1[i] = (int*)malloc(sizeof(int)*m2);
//判断函数返回值是否为0
if(arr1[i] == NULL) return 0;
for(int j=0; j<m2; j++){
scanf("%d", &arr2[i][j]);
}
}
for(int i=0; i<n; i++)
for(int j=0; j<m2; j++)
printf("%d ",arr2[i][j]);
吃了大亏.浪废了很多时间去排除错误.
在运行代码时我可以肯定逻辑没有错,但是重复的代码一个可以运行,一个不可以.所以我肯定有细节出现了问题.就那么几行代码,看了半天没看出来.我休息了一下,然后再看果然发现了问题.
如果你是得道的大侠,这篇文章可能浪费你的时间,如果你坚持要看,我当然感觉很高
兴,但是希望你看完了别骂我!如果你发现我这篇文章有错误的话,你可以提出批评以及
指正,我将很乐意地接受。_
看了老铁对二维数组的认识,觉得自己有必要在实践完后系统的整理一下知识.
https://bbs.csdn.net/topics/60157289
并行计算相关知识:
任务分担需要制导指令.
当使用 parellel 制导指令产生出并行域之后,如果仅仅是多个线程执行完全相同的任务,那么只是徒增计算工作量而不能达到加速计算的目的,甚至可能相互干扰得出错误结果。
1.void main(int argc, char *argv[]) {
2. #pragma omp parallel
3. { 并行域的开始 (对应 fork)
4. printf(“Hello, World!\n”);
5. } 并行域的结束(对应 join)
6.}
OpenMP可以完成的任务分担的指令只有for、sections和single,严格意义上来说只有 for 和 sections 是任务分担指令,而 single 只是协助任务分担的指
讲的很详细
5. MPI_Send(buf,counter,datatype,dest,tag,comm)
buf:发送缓冲区的起始地址,可以是数组或结构指针;
count:非负整数,发送的数据个数;
datatype:发送数据的数据类型;
dest:整型,目的的进程号;
tag:整型,消息标志;comm:MPI进程组所在的通信域
含义:向通信域中的dest进程发送数据,数据存放在buf中,类型
————————————————
版权声明:本文为CSDN博主「木东居士」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/zhaodedong/article/details/73441318
4.mpi 矩阵相乘
接下来便开始我们的主题
实际的思想是使用0进程将矩阵切分成n份分别发送个其他的进程,再有其他的进程计算完成之后再发回0进程。
0进程进行分发,切分,以及整合矩阵。
MPI部分,先是学习的入门文档,当时惯性认为和OpenMp是一样的,指定制导指令就可以对那部分代码进行并行计算.事实是我没有将MPI 的核心弄明白.就先入为主去'做'了.结果就是怎么翻文档都找不到所谓的制导指令.然后认真将MPI 看了一遍,入了个门知道MPI是怎么回事了,MPI是通过进程间通信发送,接收来实现并行的.
MPI的实例参考,主要是二维数组的划分以及二维数组计算的通信过程
https://www.docin.com/p-639862237.html
实例参考,真正的实例
https://blog.csdn.net/qq_41311396/article/details/90297427?utm_medium=distribute.pc_relevant.none-task-blog-baidujs-1
生成随机数的讲解
https://zhidao.baidu.com/question/431958534517233884.html
MPI计算二维数组的(讲的最详细的,思路很清晰)
https://www.cnblogs.com/Romi/archive/2012/07/13/2588412.html
帮助文档

快捷键目录标题文本样式列表链接代码片表格注脚注释自定义列表LaTeX 数学公式插入甘特图插入UML图插入Mermaid流程图插入Flowchart流程图
快捷键
Markdown 图标 快捷键
撤销 Ctrl
expected ‘#pragma omp’ clause before ‘{’ token
“{”标记前应有“#pragma omp”子句
六 MPI相关
apt-get update“从源服务器下载最新的软件包列表。
从源服务器下载最新的软件包列表。
sudo apt-get install -y 同意安装过程的所有信息
语言 C C++ Fortran 77 Fortran 90
编译器 gcc g++ gfortran gfortran
MPI编译器 mpicc mpic++/mpicxx/mpiCC mpif77 mpif90
2.1 MPI程序的编译
利用 mpicc 命令编译MPI代码文件。mpicc 是编译并链接用C编写的MPI程序的命令。
mpicc mpi.c -o mpi.o
2.2 MPI程序的运行
利用 mpirun 命令运行程序。其中 -np 选项指定处理器数目。mpirun 是MPI程序的启动脚本,它可以简化作业的启动程序,并且尽可能把不同特征屏蔽掉,提供给用户一个通用的MPI并行机的概念。
mpirun -np 8 ./mpi.o
mpicc loop_add.c -lm -o loop_add -lm调用math.h库 mpicc是编译程序
mpirun -np 8 ./loop_add 指定8个线程运行
i = 1 ,sum = 5
i = 2 ,sum = 21
i = 3 ,sum = 54
i = 4 ,sum = 110
i = 5 ,sum = 195
i = 6 ,sum = 315
i = 7 ,sum = 476
i = 8 ,sum = 684
i = 9 ,sum = 945
i = 10 ,sum = 1265
i = 11 ,sum = 1650
i = 12 ,sum = 2106
i = 13 ,sum = 2639
i = 14 ,sum = 3255
i = 15 ,sum = 3960
i = 16 ,sum = 4760
i = 17 ,sum = 5661
i = 1 ,sum = 5
i = 2 ,sum = 21
i = 3 ,sum = 54
i = 4 ,sum = 110
i = 5 ,sum = 195
i = 6 ,sum = 315
i = 7 ,sum = 476
i = 8 ,sum = 684
i = 9 ,sum = 945
i = 10 ,sum = 1265
i = 11 ,sum = 1650
i = 12 ,sum = 2106
i = 13 ,sum = 2639
i = 14 ,sum = 3255
出现重复运行
mpirun -np 1 ./loop_add
指定一个进程来进行运算就不会重复,这个数字是指多个进程来多个程序,不是运行一个程序吗?
在写矩阵函数的时候出现的问题
(多写了一个h,本来是想的能够将b矩阵计算完一轮后列能够重新指向第一列,不能用外层循环的i当做列的动态索引,所以舍弃i自己再写一个索引.
但是我函数中b矩阵本来就没有用到i当索引,不也不会出现)
(图片中的情况)
//矩阵相乘,实际相乘的次数为行的3次幂,加的次数为行的2次幂
void multi(int (*a)[3], int (*b)[3]){
int one_sum=0;
int mutil[9] = {0};
int c[3][3]={0};
int h=0,k=0,n=0;
for(int i=0; i<3; i++){
//h主要是起到指向换行的作用,在一行数计算完成后换行,计算下一行的数值,换完所有行,重置为0
//k主要是起到指向换列的作用,在计算出一个新的数值之后换列再计算下一个数值,换完所有列,重置为0
for(int r=0; r<3; r++){//r代表着b数组一个列循环完要循环下一个列了
for(int j=0; j<3; j++){
one_sum += a[i][j]*b[j][h+k];
//查看每一步one_sum即乘积的值
printf("%d\n",one_sum);
}
mutil[n++] = one_sum;
one_sum = 0;
k++;
}
k=0;
h++;
}
for(int i=0; i<9; i++){
printf("%d “,mutil[i]);
if(i%3==0){
printf(”\n");
}
}
}
Linux 下搜狗输入法崩溃
秩就是,矩阵A中非零子式的最高阶数,称为矩阵A的秩,记作r(A)
https://zhidao.baidu.com/question/41250067.html
累加的设计思路好说
而二维数组相乘的设计思路,还要牵扯到动态改变数组大小.考虑不同的运算规模的事情该是怎样的,对不同的运算规模进行分析,还要写结论
七 讲述如何申请动态内存的
https://blog.csdn.net/qq_41071068/article/details/90741413
包括了静态内存的,malloc calloc,free函数各自的使用方式和相互关系.
/malloc函数在stdlib.h里面,用的时候加入这个头文件/
int ** a;
int m,n,i;
scanf("%d%d",&m,&n);
a=(int**)malloc(msizeof(int)); /malloc函数在stdlib.h里面,用的时候加入这个头文件/
for(i=0;i<m;i++)
a[i]=(int*)malloc(n*sizeof(int));
原文链接:https://blog.csdn.net/welcomeu/article/details/13094865
动态二维数组做形参:https://blog.csdn.net/jk_chen_acmer/article/details/80297411
Segmentation fault (core dumped)错误的引用没有赋值的地址就会报错
为了使程序能够符合矩阵相乘第一个的列必须和第二个行相等的条件,我两次scanf都要求输入了n,其实不好的
C语言中经常遇到的 segmentation fault 错误
https://blog.csdn.net/lds_lsj/article/details/48199101
直接拷贝(只需要换变量的)重复的代码也是需要加强注意力的,牢记它的表征,正确的方式只有把注意力集中到需要换置的位置.
printf(“please enter the size of first 2D array : m n\n”);
scanf("%d%d",&m1,&n);
//先给申请行指针的地址空间
arr1 = (int**)malloc(sizeof(int*)*m1);
for(int i=0; i<m1; i++){
//为每一行申请n个地址空间
arr1[i] = (int*)malloc(sizeof(int)*n);
//判断函数返回值是否为0
if(arr1[i] == NULL) return 0;
for(int j=0; j<n; j++){
scanf("%d",&arr1[i][j]);
}
}
for(int i=0; i<m1; i++)
for(int j=0; j<n; j++)
printf("%d ",arr1[i][j]);
//输入你即将输入的第二个数组的大小
printf("please enter the size of second 2D array : m n\n");
scanf("%d%d",&n1,&m2);
arr2 = (int**)malloc(sizeof(int*)*n2);
//判断函数返回值是否为0
if(arr1 == NULL || arr2 == NULL)
return 0;
for(int i=0; i<n1; i++){
//为每一行申请n个地址空间
arr1[i] = (int*)malloc(sizeof(int)*m2);
//判断函数返回值是否为0
if(arr1[i] == NULL) return 0;
for(int j=0; j<m2; j++){
scanf("%d", &arr2[i][j]);
}
}
for(int i=0; i<n; i++)
for(int j=0; j<m2; j++)
printf("%d ",arr2[i][j]);
吃了大亏.浪废了很多时间去排除错误.
在运行代码时我可以肯定逻辑没有错,但是重复的代码一个可以运行,一个不可以.所以我肯定有细节出现了问题.就那么几行代码,看了半天没看出来.我休息了一下,然后再看果然发现了问题.
如果你是得道的大侠,这篇文章可能浪费你的时间,如果你坚持要看,我当然感觉很高
兴,但是希望你看完了别骂我!如果你发现我这篇文章有错误的话,你可以提出批评以及
指正,我将很乐意地接受。_
看了老铁对二维数组的认识,觉得自己有必要在实践完后系统的整理一下知识.
https://bbs.csdn.net/topics/60157289
并行计算相关知识:
任务分担需要制导指令.
当使用 parellel 制导指令产生出并行域之后,如果仅仅是多个线程执行完全相同的任务,那么只是徒增计算工作量而不能达到加速计算的目的,甚至可能相互干扰得出错误结果。
1.void main(int argc, char *argv[]) {
2. #pragma omp parallel
3. { 并行域的开始 (对应 fork)
4. printf(“Hello, World!\n”);
5. } 并行域的结束(对应 join)
6.}
OpenMP可以完成的任务分担的指令只有for、sections和single,严格意义上来说只有 for 和 sections 是任务分担指令,而 single 只是协助任务分担的指
讲的很详细
5. MPI_Send(buf,counter,datatype,dest,tag,comm)
buf:发送缓冲区的起始地址,可以是数组或结构指针;
count:非负整数,发送的数据个数;
datatype:发送数据的数据类型;
dest:整型,目的的进程号;
tag:整型,消息标志;comm:MPI进程组所在的通信域
含义:向通信域中的dest进程发送数据,数据存放在buf中,类型
————————————————
版权声明:本文为CSDN博主「木东居士」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/zhaodedong/article/details/73441318
4.mpi 矩阵相乘
接下来便开始我们的主题
实际的思想是使用0进程将矩阵切分成n份分别发送个其他的进程,再有其他的进程计算完成之后再发回0进程。
0进程进行分发,切分,以及整合矩阵。
MPI部分,先是学习的入门文档,当时惯性认为和OpenMp是一样的,指定制导指令就可以对那部分代码进行并行计算.事实是我没有将MPI 的核心弄明白.就先入为主去'做'了.结果就是怎么翻文档都找不到所谓的制导指令.然后认真将MPI 看了一遍,入了个门知道MPI是怎么回事了,MPI是通过进程间通信发送,接收来实现并行的.
MPI的实例参考,主要是二维数组的划分以及二维数组计算的通信过程
https://www.docin.com/p-639862237.html
实例参考,真正的实例
https://blog.csdn.net/qq_41311396/article/details/90297427?utm_medium=distribute.pc_relevant.none-task-blog-baidujs-1
生成随机数的讲解
https://zhidao.baidu.com/question/431958534517233884.html
MPI计算二维数组的(讲的最详细的,思路很清晰)
https://www.cnblogs.com/Romi/archive/2012/07/13/2588412.html