第五讲 openmp
OpenMP并行模型
程序员视角
执行模型
编程环境配置
编程模型
编译指示格式
- 编译指示格式
- #pragma omp directive_name[clause[clause]……]
- 条件编译
- 如果使用的平台支持openmp则。。
- 不支持的话就按照串行方式,保证结果正确
- 大小写敏感
- 使用库函数需要包含头文件
运行时库,查询函数
并行区域结构
hello world程序
#include<stdio.h>
#include<stdlib.h>
#include<omp.h>
void Hello(void);
int main(int argc,char* argv[]){
int thread_count=strtol(argv[1],NULL,10);
#pragma omp parallel num_threads(thread_count)
Hello();
return 0;
}
void Hello(void){
int my_rank=omp_get_thread_num();
int thread_count=omp_get_num_threads();
print("Hello from thread %d of %d\n",my_rank,thread_count);
}
为防止编译器不支持openMP
梯形积分法
临界区指令
归约
并行循环
OpenMp数据并行:并行循环
局限和语义
必须提前看到for循环就能看到有多少任务
带break、goto之类的不支持
不支持依赖的(例如斐波那契数列,每次计算都要用到前面的数)
简单并行化循环的版本
同步
openmp隐式同步
在要并行的语句前隐式的有开始并行和join之类的
并行for指示的各种形式
数据依赖(中间跳过了一部分,只讲了下面的几个ppt,跳过p39、)
第一个存在数据依赖
第二个不存在依赖
例子
气泡排序(🌟)
内层和外层哪个存在循环依赖??
都存在
外层:每次循环数组的顺序都发生了变化,下一次循环依赖上次循环的结果,存在循环依赖关系
内层,每次都要比较a[i]和a[i+1],并要交换两者位置,存在循环依赖关系
气泡排序内外层都存在依赖,怎么进行并行化
- 解决方法
- 第一轮奇数项和他的下一个比较,第二轮偶数项和她的下一个比较
- 每一轮之间不存在依赖了
- 串行的代码
- 并行代码
- 有什么问题
- 每次大循环的时候频繁地创建线程以及销毁线程,耗费系统资源
- 怎么改进?
- 把创建线程拿到大循环外面
- 不用加parrallel_for啥的,因为不是对外循环并行化。只是现在外面生成线程,在执行内循环的时候在写pragma omp for,把任务分到线程上
循环调度
什么都不写的话默认static,最大块
静态分配
不指定的话默认为threads,指定的话变成循环分配,下面是制定了static(2)
在执行任务之前划分好,执行的时候
动态分配
谁先执行好把剩下的最后一块给哪个线程
guided动态划分
剩余任务数➗二倍的线程数
更多属性
局部性
重用
===========中间跳过了
后面全都跳过了