提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
前言
本文学习的是配置openmpi环境,并写出相应c语言和fortran程序,依然以函数的累加为例子。
一、配置openmpi
不多啰嗦,直接放网站
下载openmpi-4.1.4的地址
从上面地址下载压缩包后,按以下命令操作
tar -zxvf openmpi-4.1.4.tar.gz
cd openmpi-4.1.4
./configure //本处会等待一段时间
make all //本处也会等待一段时间
make install //本处依然会等待一段时间
以上操作亲测有效,非常帅气,萌新们可以对着控制台拍摄视频,发送朋友圈,并配上文字,你是黑客啦!
接下来要测试你的openmp是否安装成功,按如下代码顺序执行
cd /openmpi-4.1.4/examples/
mpicc -o hello_c hello_c.c
mpirun hello_c
以上就是简单执行了个helloworld,如果执行成功说明安装成功。
二、程序设计
1.并行计算1~1000的3nn+2*n的累加,c语言版
代码如下(示例):
#include<stdio.h>
#include"omp.h"
void test()
{
int n=0;
int i;
for (i = 1; i < 1001; i++)
{
n = n+ 3*i*i+2*i;
}
}
void main()
{
float startTime = omp_get_wtime();
int i;
#pragma omp parallel for num_threads(2)
for (i = 0; i < 80000; i++)
{
test();
}
float endTime = omp_get_wtime();
printf("指定 2 个线程,执行时间: %f\n", endTime - startTime);
startTime = endTime;
#pragma omp parallel for num_threads(4)
for (i = 0; i < 80000; i++)
{
test();
}
endTime = omp_get_wtime();
printf("指定 4 个线程,执行时间: %f\n", endTime - startTime);
startTime = endTime;
#pragma omp parallel for num_threads(8)
for (i = 0; i < 80000; i++)
{
test();
}
endTime = omp_get_wtime();
printf("指定 8 个线程,执行时间: %f\n", endTime - startTime);
startTime = endTime;
#pragma omp parallel for num_threads(12)
for (i = 0; i < 80000; i++)
{
test();
}
endTime = omp_get_wtime();
printf("指定 12 个线程,执行时间: %f\n", endTime - startTime);
startTime = endTime;
for (i = 0; i < 80000; i++)
{
test();
}
endTime = omp_get_wtime();
printf("不使用OpenMP多线程,执行时间: %f\n", endTime - startTime);
startTime = endTime;
system("pause");
}
可以看到openmp的结果都是用带井号的注释实现的
2.并行计算1~1000的3nn+2*n的累加,fortran语言版
代码如下(示例):
program main
include 'omp_lib.h'
integer N,M,i,c1,c2,c_rate
real(kind=8) t
N=1000
t=0.0
call system_clock(c1, c_rate)
!$OMP PARALLEL DO
do i=1,N
!$OMP CRITICAL
t=t+3*i*i+2*i;
!$OMP END CRITICAL
M=OMP_get_num_threads()
enddo
call system_clock(c2,c_rate)
time = c2-c1
write(*, "('t = ', F20.5, ' running on ', I3, ' threads.')") t,M
write(*,*) 'time=',time
stop
end
上面的代码一开始编写的时候也遇到了bug,就是用并行计算,每次算的结果都是错误的,我怀疑是线程之间传信息的时候,因为通信问题导致一些数据的丢失,一般会丢失个百分之一的数据,丢的不算多,但是算错了就是算错了。
所以最后用
!
O
M
P
C
R
I
T
I
C
A
L
和
!
OMP CRITICAL和 !
OMPCRITICAL和!OMP END CRITICAL
把要求值的部分锁住了,也就是每一时刻只有一个线程可以访问这个变量t,这样可能带来许多效率的损失,实际上最好的方法应该是用归约实现。
但是我用归约实现代码的时候,它还是算不对,很奇怪。
总结
fortran作为上世纪五十年代的古老语言,它运行速度极快,在并行计算任务中具有得天独厚的优势。闯过编译原理和计算机组成原理的计算机学子啊,岂能被区区编程语言难倒?
要知道,智者不入爱河,愚者重蹈覆辙,寡王一路硕博,建设美丽祖国!
加油!