openmp学习心得(一)
主要在vs2015下使用OMP,写一些自己omp的学习心得:
一、在VS2015下OpenMP的使用:
1、VS2015也仅仅支持OpenMP2.0版本,VS对OpenMP的支持并不太好。
2、在VS下使用OPenMP需要在项目设置中找到,项目-->语言-->OpenMP支持中,选择是,下图所示:
并且在头文件中包含"omp.h"即可支持OpenMP了。
二、关于数据属性
1、shared 用来声明一个或者多个共享变量,在并行区会有数据竞争。
2、private 声明私有变量。
1 void test_private()
2 {
3 printf("--before parallel--------------\n");
4 int a =100 ;
5 printf("a=%d\n", a);
6 printf("--parallel--------------\n");
7 #pragma omp parallel for private(a)
8 for (int i = 0; i < 10; i++)
9 {
10 a = i;//如果a没有被初始化,会提示a没有初始化,即使在并行前做了初始化也会有错误!
11 printf("a=%d\n", a);
12 }
13 printf("--after parallel--------------\n");
14 printf("a=%d\n", a);
15 }
结果输出:
--before parallel--------------
a=100
--parallel--------------
a=0
a=6
a=8
a=1
a=2
a=5
a=9
a=3
a=4
a=7
--after parallel--------------
a=100
3、default default(shared):表示并行区域内的共享变量在不指定的情况下都是shared属性;default(none):表示必须显式指定所有共享变量的数据属性,否则会报错,除非变量有明确的属性定义(比如循环并行区域的循环迭代变量只能是私有的。
4、firstprivate 继承并行区域之外的变量的值,用于在进入并行区域之前进行一次初始化。
void test_firstprivate()
{
printf("--before parallel--------------\n");
int a = 100;
printf("a=%d\n", a);
printf("--parallel--------------\n");
#pragma omp parallel for firstprivate(a) num_threads(3)
for (int i = 0; i < 10; i++)
{
printf("ID=%d,i=%d,a=%d\n",omp_get_thread_num(),i,a);
a = i;//对于某个线程来说,firstprivate仅仅进行一次初始化
}
printf("--after parallel--------------\n");
printf("a=%d\n", a); }
结果如下:
--before parallel--------------
a=100
--parallel--------------
ID=0,i=0,a=100
ID=0,i=1,a=0
ID=2,i=7,a=100
ID=0,i=2,a=1
ID=1,i=4,a=100
ID=2,i=8,a=7
ID=0,i=3,a=2
ID=2,i=9,a=8
ID=1,i=5,a=4
ID=1,i=6,a=5
--after parallel--------------
a=100
5、lastprivate 如果需要在并行区域内的私有变量经过计算后,在退出并行区域时,需要将其值赋给同名的共享变量,就可以使用lastprivate完成。
1 void test_lastprivate()
2 {
3 printf("--before parallel--------------\n");
4 int a = 100;
5 printf("a=%d\n", a);
6 printf("--parallel--------------\n");
7 #pragma omp parallel for lastprivate(a) num_threads(3)
8 for (int i = 0; i < 10; i++)
9 {
10 a = i;
11 printf("ID=%d,i=%d,a=%d\n", omp_get_thread_num(), i, a);
12
13 }
14 printf("--after parallel--------------\n");
15 printf("a=%d\n", a); //获得逻辑上a的最后一个值,而不是最后一个线程的a值
16 }
结果如下:
--before parallel--------------
a=100
--parallel--------------
ID=0,i=0,a=0
ID=0,i=1,a=1
ID=1,i=4,a=4
ID=2,i=7,a=7
ID=0,i=2,a=2
ID=2,i=8,a=8
ID=1,i=5,a=5
ID=0,i=3,a=3
ID=1,i=6,a=6
ID=2,i=9,a=9
--after parallel--------------
a=9
6、threadprivate 指定全局变量被OpenMP所有的线程各自产生一个私有的拷贝,即各个线程都有自己私有的全局变量。一个很明显的区别在于,threadprivate并不是针对某一个并行区域,而是整个于整个程序,所以,其拷贝的副本变量也是全局的,即在不同的并行区域之间的同一个线程也是共享的。threadprivate只能用于全局变量或静态变量。
7、copyin 用于将主线程中threadprivate变量的值拷贝到执行并行区域的各个线程的threadprivate变量中,从而使得team内的子线程都拥有和主线程同样的初始值。copyin中的参数必须被声明成threadprivate的。
8、copyprivate用于将线程私有副本变量的值从一个线程广播到执行同一并行区域的其他线程的同一变量。copyprivate只能用于single指令的子句中,在一个single块的结尾处完成广播操作。copyprivate只能用于private/firstprivate或threadprivate修饰的变量。
openmp学习心得(一)的更多相关文章
- openmp学习心得(二)----常见的运行时库函数
omp_set_dynamic();如果设置了动态调整,并行区域会根据系统的资源状况,动态分配线程的数量.好像仅仅有0和非0的区别,设置为0不进行动态分配. omp_get_num_threads,o ...
- 我的MYSQL学习心得(一) 简单语法
我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据类型 我的MYSQL学习心得(五) 运 ...
- 我的MYSQL学习心得(二) 数据类型宽度
我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据类型 我的MYSQL学习心得(五) 运 ...
- 我的MYSQL学习心得(三) 查看字段长度
我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(四) 数据类型 我的MYSQL学习心得(五) 运 ...
- 我的MYSQL学习心得(四) 数据类型
我的MYSQL学习心得(四) 数据类型 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(五) 运 ...
- 我的MYSQL学习心得(五) 运算符
我的MYSQL学习心得(五) 运算符 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据 ...
- 我的MYSQL学习心得(六) 函数
我的MYSQL学习心得(六) 函数 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据类 ...
- 我的MYSQL学习心得(七) 查询
我的MYSQL学习心得(七) 查询 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据类 ...
- 我的MYSQL学习心得(八) 插入 更新 删除
我的MYSQL学习心得(八) 插入 更新 删除 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得( ...
随机推荐
- JS003. 事件监听和监听滚动条的三种参数( addEventListener( ) )
全局 1 window.addEventListener('scroll', () => { 2 console.log('------') 3 console.log(document.doc ...
- CUDA 矩阵乘法终极优化指南
作者:马骏 | 旷视 MegEngine 架构师 前言 单精度矩阵乘法(SGEMM)几乎是每一位学习 CUDA 的同学绕不开的案例,这个经典的计算密集型案例可以很好地展示 GPU 编程中常用的优化技巧 ...
- scrum项目冲刺_day05总结
摘要:今日完成任务. 1.语音识别完成 2.搜索功能实现了从数据库中的查询 总任务: 一.appUI页面(已完成) 二.首页功能: 1.图像识别功能(已完成) 2.语音识别功能(已完成) 3.垃圾搜索 ...
- Node.js躬行记(10)——接口日志查询
当运营向我们上报BUG时,我们第一时间是捕获相关的接口.从监控系统中,就可以查到用户使用时接口的请求和响应数据. 若接口的请求正常,那么就需要深入到接口代码中,查看相关的日志,通常会先浏览数据库查询语 ...
- Linux从头学13:想彻底搞懂“系统调用”的底层原理?建议您别错过这篇【调用门】
作 者:道哥,10+年嵌入式开发老兵,专注于:C/C++.嵌入式.Linux. 关注下方公众号,回复[书籍],获取 Linux.嵌入式领域经典书籍:回复[PDF],获取所有原创文章( PDF 格式). ...
- TP5模型开启事务
和Db开启事务类似,Db是静态方法 $userObj = new UserModel(); $userObj->startTrans(); try { $userObj->data($da ...
- Java基础系列(34)- 什么是数组
数组的定义 数组是相同类型数据的有序集合 数组描述的是相同类型的若干个数据,按照一定的先后次序排列组合而成 其中,每一个数据称作一个数组元素,每个数组元素可以通过一个下标来访问它们
- php nginx 路径批量配置
* 假设 E:\upload 作为图片上传的位置 nginx 做web服务 * 创建文件conf.php 放到这个目录下 <?php function handleDir($it, &$ ...
- Appium自动化测试时为什么要自己封装find方法
官方的find_element方法不能很好地处理异常,所以自行封装,以智能化处理各种异常
- 使用form插件 和ajax 结合使用 没有调用success的原因
当我做文件上传的时候出现不调用success方法 将datype: 'json' 注释掉后成功响应 浏览器显示200状态码,并且响应头为json格式,格式ajax不认为它是json,所以一直执行错误 ...