在fortran下进行openmp并行计算编程
最近写水动力的程序,体系太大,必须用并行才能算的动,无奈只好找了并行编程的资料学习了。我想我没有必要在博客里开一个什么并行编程的教程之类,因为网上到处都是,我就随手记点重要的笔记吧。这里主要是openmp的~
1 临界与归约
在涉及到openmp的并行时,最需要注意的就是被并行的区域中的公共变量,对于需要reduce的变量,尤其要注意,比如这段代码:
program main
implicit none
include 'omp_lib.h'
integer N,M,i
real(kind=8) t
N=20000
t=0.0
!$OMP PARALLEL DO
do i=1,N
t=t+float(i);
M=OMP_get_num_threads()
enddo
write(*, "('t = ', F20.5, ' running on ', I3, ' threads.')") t,M
pause
stop
end
串行代码可以很容易的得到正确结果:
t = 200010000.00000 running on 1 threads.
不幸的是,如果是并行的话,可能每次都得到一个不同的结果:
t = 54821260.00000 running on 8 threads.
t = 54430262.00000 running on 8 threads.
....
原因很简单,假设do被并行了两个线程,A1,A2,则每个线程都可以t,在其中一个线程访问t的时候,另一个线程修改了t,导致t的某些值“丢了”。解决方法有两种,第一种就是“临界”,就是锁定t:
!$OMP PARALLEL DO
do i = , N
!$OMP CRITICAL
t = t+float(i)
!$OMP END CRITICAL
M = OMP_get_num_threads()
enddo
这样每个时刻只有一个线程能访问这个变量。显然,这种方法会遇到“短木板瓶颈”,更高效的方法是使用“归约”:
!$OMP PARALLEL DO REDUCTION(+:t)
do i = , N
t = t+float(i)
M = OMP_get_num_threads()
enddo
此时程序会自动在内部实现储存部分和之类的操作。这个方法比临界要高效的多,这是我这里运行的结果:临界0.005s, 归约0.003s。对于大任务,速度会更快。
2 条件并行
有时,对于小的循环,多线程的消耗超过了并行的节省时间,显然这是就不值得并行了。比如
do i = , N
t = t+(sin(float(i))+2.0)**0.3+abs(cos(log(float(i))))**0.7
M = OMP_get_num_threads()
enddo
发现:
N 20000 5000
tserial 0.027s 0.003
tparallel 0.013s 0.004
推断在N>5000时应该并行更有效,可以加上条件编译:
!$OMP PARALLEL DO REDUCTION(+:t) if(N > 5000)
3 负载平衡
不同线程间的工作量“不平等”是个很麻烦的问题,他会大大降低程序并行效率,比如这个程序:
N =
!$OMP PARALLEL DO PRIVATE(j)
do i = , N
do j = i, N
a(j, i) = fun(i, j)
enddo
enddo
其中fun是个费时的函数,串行与8核CPU并行的时间比较:
serial:3m28.007s;paralle:49.940s 加速比 4.1 太低了
这个显然与CPU个数无关。分析上面的循环发现,i=1时内层需要N个循环,而i=2500时候内部仅仅N/2个循环,极其不平衡,因此可以显式指定其调动模式,改进负载平衡。NAMD中有个LDB模块就是干这个的。SCHEDULE一般格式:
SCHEDULE(type, chunk)
可以比较一下:
!$OMP PARALLEL DO SCHEDULE(static,1) 34.955s
!$OMP PARALLEL DO SCHEDULE(dynamic,1) 29.773s
!$OMP PARALLEL DO SCHEDULE(guided,1) 53.116s
!$OMP PARALLEL DO SCHEDULE(static,500) 48.822s
!$OMP PARALLEL DO SCHEDULE(dynamic,500) 50.485s
!$OMP PARALLEL DO SCHEDULE(guided,500) 51.611s
需要注意的是,实际中很难一下看出那种调度方式最好。通常需要实际试验,这还与你调用的CPU数目有关。SCHEDULE中,增大chunk可以提高缓存命中率,但是以降低负载平衡为代价的
在fortran下进行openmp并行计算编程的更多相关文章
- OpenMP并行编程
什么是OpenMP?“OpenMP (Open Multi-Processing) is an application programming interface (API) that support ...
- [OpenMP] 并行计算入门
OpenMP并行计算入门 个人理解 OpenMP是一种通过共享内存并行系统的多处理器程序设计的编译处理方案,通过预编译指令告诉编译器哪些代码块需要被并行化,通过拷贝代码块实现并行程序.对于循环的并行化 ...
- Openmp多线程编程练习
环境配置 一般使用Visual Studio2019来作为openmp的编程环境 调试-->属性-->C/C++-->所有选项-->Openmp支持改为 是(可以使用下拉菜单) ...
- Linux下的C Socket编程 -- server端的继续研究
Linux下的C Socket编程(四) 延长server的生命周期 在前面的一个个例子中,server在处理完一个连接后便会立即结束掉自己,然而这种server并不科学啊,server应该是能够一直 ...
- 分享在winform下实现模块化插件编程-优化版
上一篇<分享在winform下实现模块化插件编程>已经实现了模块化编程,但我认为不够完美,存在以下几个问题: 1.IAppContext中的CreatePlugInForm方法只能依据完整 ...
- Linux下的C Socket编程 -- server端的简单示例
Linux下的C Socket编程(三) server端的简单示例 经过前面的client端的学习,我们已经知道了如何创建socket,所以接下来就是去绑定他到具体的一个端口上面去. 绑定socket ...
- Linux下的C Socket编程 -- 获取对方IP地址
Linux下的C Socket编程(二) 获取域名对应的IP地址 经过上面的讨论,如果我们想要连接到远程的服务器,我们需要知道对方的IP地址,系统函数gethostbyname便能够实现这个目的.它能 ...
- Linux下的C Socket编程 -- 简介与client端的处理
Linux下的C Socket编程(一) 介绍 Socket是进程间通信的方式之一,是进程间的通信.这里说的进程并不一定是在同一台机器上也有可能是通过网络连接的不同机器上.只要他们之间建立起了sock ...
- windows下的socket网络编程
windows下的socket网络编程 windows下的socket网络编程 clinet.c 客户端 server.c 服务器端 UDP通信的实现 代码如下 已经很久没有在windows下编程了, ...
随机推荐
- 常用的 Python 爬虫技巧总结
用python也差不多一年多了,python应用最多的场景还是web快速开发.爬虫.自动化运维:写过简单网站.写过自动发帖脚本.写过收发邮件脚本.写过简单验证码识别脚本. 爬虫在开发过程中也有很多复用 ...
- SU Demos-02Filtering-06Sukfilter
本demo中数学原理纯粹不知道,看来以后需要抓紧时间补课了,只附图. 运行结果图如下:
- Xamarin.iOS调试提示需要iOS SDK
Xamarin.iOS调试提示需要iOS SDK 错误信息:The version of Xamarin.iOS requires th iOS 9.3 SDK (shipped with Xco ...
- MAXIMO移动解决方案在库存管理中的PDA应用系统
随着无线网络通信技术.掌上电脑技术以及条形码自动识别技术的推广使用,为了强化MAXIMO系统库存管理的功能,着手开发MAXIMO移动应用解决方案. 该解决方案集成了无线局域网络通信.掌上电脑以及条形码 ...
- Chart系列(一):Chart的基本元素
如何使用一个Chart,则首先必须要了解其组织结构,其次知道其API. Chart元素 首先,来看看Chart组成元素. Axis Label:坐标轴标签 Axis Title:坐标轴标题 C ...
- css构造块级元素
css 1. 宽高width:数值;height:数值;也可用百分比!长高的设置不会被后代继承2. 背景(1)背景颜色background-color:颜色值;元素的背景颜色默认为transparen ...
- hbase0.95.2部署
hbase0.95.2部署 下载安装包 hbase-0.95.2-cdh5.0.0-beta-1.tar.gz hbase需对应hadoop版本 解压 tar zxvf hbase-0.95.2-cd ...
- Android SDK Manager无法更新,内容显示不全的解决办法
最近在初学android开发,在更新SDK的时候遇到了麻烦. 发现Extras文件夹下为空,没有内容,包括sdk列表也不全面,更新也没有反应 解决方法: 1.在SDK Manager下Tools-&g ...
- JS设计模式一:单例模式
单例模式 单例模式也称作为单子模式,更多的也叫做单体模式.为软件设计中较为简单但是最为常用的一种设计模式. 下面是维基百科对单例模式的介绍: 在应用单例模式时,生成单例 ...
- 【BZOJ】2761: [JLOI2011]不重复数字(set+巨水题+超坑题)
http://www.lydsy.com/JudgeOnline/problem.php?id=2761 太水了,不说了. 但是这格式错误我已经没话说了....行末不能有空格 #include < ...