第五讲 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动态划分
剩余任务数➗二倍的线程数

更多属性

局部性

重用
===========中间跳过了


后面全都跳过了
