OpenMP学习笔记<一>

本文介绍并行程序设计的基本思路及OpenMP的核心概念和技术细节。涵盖并行任务划分、通信、组合与映射等步骤,并深入探讨OpenMP的执行模式、编程指导指令、API函数及环境变量。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

##并行程序设计思路 并行程序设计和串行的稍微不同, 大概经历下面四个阶段: 划分: 将计算分解成尽可能多的小任务, 可以按处理对象数据进行域分解, 也可以按计算任务进行功能分解. 这两种分解要做到数据集和计算集不相交. 通信: 划分产生的任务, 一般不能完全独立执行, 需要进行数据通信 组合: 根据任务的局部性, 将小任务组合成更大的任务 映射: 将组合后的多个任务分配到多个处理器上, 并期望获得算法的最优性能减少算法的执行时间

#OpenMp 基本概念 OpenMP 属于共享内存编程模型的技术, 通过在源代码中添加指导注释, 成为编译指导: #pragma omp parallel

OpenMP 支持的语言包括 C/C++ 和 Fortran, 支持开源编译器 gcc/g++, 下面首先了解OpenMP 的执行模式和三大要素. ##执行模式 OpenMP 采用 fork-join 的模式, 其中 fork 创建新线程或者唤醒已有的线程, jion 即多线程的会合. 主线程在运行过程中, 需要并行计算的时候, 派生出线程来执行并行任务. 在并行代码执行结束后, 派生线程退出或阻塞, 控制流程回到主线程上. ##编程要素 ###1. 编程指导 在 C/C++ 中, OpenMP 的编译指导指令是以 #pragma omp 开头的, 形式如下:

#pragma omp 指令 [子句 [子句]....]

指导指令和子句按照功能大体分为四类: 并行域控制类 任务分担类 同步控制类 数据环境类

下面是 OpenMP 规范的指令:

parallel* :    用在一个结构块之前,表示这段代码将被多个线程并行执行
for* :    用于for循环语句之前,表示将循环计算任务分配到多个线程中并行执行,以实现任务分担,必须由编程人员自己保证每次循环之间无数据相关性
parallel for* :    parallel和for指令的结合,也是用在for循环语句之前,表示for循环体的代码将被多个线程并行执行,它同时具有并行域的产生和任务分担两个功能
sections* :    用在可被并行执行的代码段之前,用于实现多个结构块语句的任务分担,可并行执行的代码段各自用section指令标出
parallel sections* :    parallel和sections两个语句的结合,类似于parallel for
single* :    用在并行域内,表示一段只被单个线程执行的代码
critical* :    用在一段代码临界区之前,保证每次只有一个OpenMP线程进入
flush* :    保证各个OpenMP线程的数据影像的一致性
barrier* :    用于并行域内代码的线程同步,线程执行到barrier时要停下等待,直到所有线程都执行到barrier时才能继续往下执行
atomic* :    用于指定一个数据操作需要原子性地完成
master* :    用于指定一段代码由主线程执行
threadprivate* :    用于指定一个或多个变量是线程专用。

相应的 OpenMP 子句:

private* :    指定一个或多个变量在每个线程中都有它自己的私有副本
firstprivate* :    指定一个或多个变量在每个线程都有它自己的私有副本,并且私有变量要在进入并行域或认为分担域时,继承主线程中的同名变量的值作为初值
lastprivate* :    是用来指定将线程中的一个或多个私有变量的值在并行处理结束后复制到主线程中的同名变量中,负责拷贝的线程是for或sections任务分担中的最后一个线程
reduction* :    用来指定一个或多个变量是私有的,并且在并行处理结束后这些变量要执行指定的归约运算,并将结果返回给主线程同名变量
nowait* :    指出并发线程可以忽略其他制导指令暗含的路障同步
num_threads* :    指定并行域内的线程的数目
schedule* :    指定for任务分担中的任务分配调度类型
shared* :    指定一个或多个变量为多个线程间的共享变量
copyprivate* :    配合single指令,将指定线程的专有变量广播到并行域内其他线程的同名变量中
copyin* :    用来指定一个threadprivate类型的变量需要用主线程同名变量进行初始化
default* :    用来指定并行域内的变量的使用方式,缺省是shared。 ## API 函数


omp_in_parallel:    判断当前是否在并行域中
omp_get_thread_num:    返回线程号
omp_set_num_threads:    设置后续并行域中的线程个数
omp_get_num_threads:    返回当前并行区域中的线程数
omp_get_max_threads:    获取并行域可用的最大线程数目
omp_get_num_procs:    返回系统中处理器个数
omp_get_dynamic:    判断是否支持动态改变线程数目
omp_set_dynamic:    启用或关闭线程数目的动态改变
omp_get_nested:    判断系统是否支持并行嵌套
omp_set_nested:    启用或关闭并行嵌套
omp_init(_nest)_lock:    初始化一个(嵌套)锁
omp_destroy(_nest)_lock:    销毁一个(嵌套)锁
omp_set(_nest)_lock:    (嵌套)加锁操作
omp_unset(_nest)_lock:    (嵌套)解锁操作
omp_test(_nest)_lock:    非阻塞的(嵌套)加锁
omp_get_wtime:    获取wall time时间
omp_set_wtime:    设置wall time时间。 ##环境变量 <code>OMP_SCHEDULE</code>: 只能用到 for, parallel for中。它的值就是处理器中循环的次数

OMP_NUM_THREADS: 定义执行中最大的线程数

OMP_DYNAMIC: 通过设定变量值TRUE或FALSE, 来确定是否动态设定并行域执行的线程数

OMP_NESTED: 确定是否可以并行嵌套

### WRF 数值模拟学习资源汇总 对于希望深入理解 Weather Research and Forecasting (WRF) 模型及其应用的研究人员来说,存在多种途径获取高质量的学习材料。这些资源不仅涵盖了理论基础,还包括实际操作指南。 #### 官方文档与教程 官方提供的文档是最权威的信息源之。UCAR(University Corporation for Atmospheric Research)维护着详细的在线手册和教程,适合不同层次的使用者查阅[^2]。这类资料通常会随着版本更新而持续改进,确保用户能够获得最新的配置方法和技术细节说明。 #### 实战案例分析 通过具体的应用场景来掌握软件工具是非常有效的学习方式。例如,在研究台风菲特(Fitow)期间,有学者分享了完整的实验过程记录,包括但不限于数据准备、参数设定以及结果验证等多个环节的具体实现步骤。此类实战经验有助于加深对整个工作流的理解,并能帮助解决实践中遇到的实际问题。 #### 技术博客与社区讨论 互联网上有许多个人或团队撰写的关于WRF的技术文章,它们往往包含了作者独特的见解和个人积累的小技巧。特别是当涉及到特定环境下的部署或是优化性能等方面的话题时,来自线开发者的建议尤为珍贵[^4]。此外,积极参与相关论坛交流也是快速提升技能的好办法;在这里可以找到志同道合的朋友共同探讨难题,互相启发思路。 #### 并行计算平台支持 鉴于气象预报任务常常涉及大规模的数据集处理及复杂物理过程仿真,因此熟悉高性能计算机(HPC)上的作业提交机制至关重要。针对这点,某些机构提供了专门面向初学者编写的入门级指导材料,介绍了必要的Linux命令行操作知识以及MPI/OpenMP编程接口等内容[^3]。这使得即使是没有太多超级计算背景的人也能顺利开展基于集群系统的科研活动。 ```bash # 示例:登录远程服务器并执行简单命令 ssh username@remote_host cd /path/to/project_directory ls -l ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值