OpenMP 简单的规约
▶ 简单的计算和规约
● 第一种方法,将全局和的指针传入工作函数中进行加和,使用 critical 来控制临界区的访问
- #include <stdio.h>
- #include <stdlib.h>
- #include <omp.h>
- const int thread = ;
- void work(int* globalSum)
- {
- #pragma omp critical // 使用 critical 来控制临界区的访问
- *globalSum += omp_get_thread_num();
- return;
- }
- int main(int argc, char* argv[])
- {
- int threadReal, globalSum;
- if (argc > && *argv[] > ''&& *argv[] < '')
- threadReal = atoi(argv[]);
- else
- threadReal = thread;
- globalSum = ; // 初始化全局和
- #pragma omp parallel num_threads(threadReal)
- work(&globalSum); // 将全局和的指针传给每个线程进行计算
- printf("\nglobalSum = %d\n", globalSum);
- getchar();
- return ;
- }
● 输出结果,下面几种方法的输出结果均相同,不再重复罗列
- globalSum =
● 第二种方法,使用局部变量,在主函数中进行加和
- #include <stdio.h>
- #include <stdlib.h>
- #include <omp.h>
- const int thread = ;
- int work()
- {
- return omp_get_thread_num();
- }
- int main(int argc, char* argv[])
- {
- int threadReal, globalSum;
- if (argc > && *argv[] > ''&& *argv[] < '')
- threadReal = atoi(argv[]);
- else
- threadReal = thread;
- globalSum = ;
- #pragma omp parallel num_threads(threadReal)
- {
- int localSum = work(); // 使用局部变量
- #pragma omp critical
- globalSum += localSum; // 将局部和加到全局和中
- }
- printf("\nglobalSum = %d\n", globalSum);
- getchar();
- return ;
- }
● 第三种方法,使用规约子句
- #include <stdio.h>
- #include <stdlib.h>
- #include <omp.h>
- const int thread = ;
- int work()
- {
- return omp_get_thread_num();
- }
- int main(int argc, char* argv[])
- {
- int threadReal, globalSum;
- if (argc > && *argv[] > ''&& *argv[] < '')
- threadReal = atoi(argv[]);
- else
- threadReal = thread;
- globalSum = ;
- #pragma omp parallel num_threads(threadReal) reduction(+ : globalSum)// 要求对 globalSum 使用加法规约
- globalSum += work();
- printf("\nglobalSum = %d\n", globalSum);
- getchar();
- return ;
- }
● 第四种方法,使用 parallel for 循环
- #include <stdio.h>
- #include <stdlib.h>
- #include <omp.h>
- const int thread = ;
- int work()
- {
- return omp_get_thread_num();
- }
- int main(int argc, char* argv[])
- {
- int i, threadReal, globalSum;
- if (argc > && *argv[] > ''&& *argv[] < '')
- threadReal = atoi(argv[]);
- else
- threadReal = thread;
- globalSum = ;
- #pragma omp parallel for num_threads(threadReal) reduction(+:globalSum)// 联用了规约子句和 parallel for 循环
- for (i = ; i < threadReal; i++)
- globalSum += work();
- printf("\nglobalSum = %d\n", globalSum);
- getchar();
- return ;
- }
▶ 单独的 parallel for 用法
- #include <stdio.h>
- #include <stdlib.h>
- #include <omp.h>
- const int thread = ;
- int main(int argc, char* argv[])
- {
- int i, threadReal, a[thread];
- if (argc > && *argv[] > ''&& *argv[] < '')
- threadReal = atoi(argv[]);
- else
- threadReal = thread;
- #pragma omp parallel for num_threads(threadReal)
- for (i = ; i < threadReal; i++)// 注意,把下面的 a[i] = i 写到括号里来会报错 “OpenMP“for”语句中的增量格式不正确”
- a[i] = i;
- for (i = ; i < thread; i++)
- printf("a[%2d] = %2d\n", i, a[i]);
- getchar();
- return ;
- }
● 输出结果
- a[ ] =
- a[ ] =
- a[ ] =
- a[ ] =
- a[ ] =
- a[ ] =
- a[ ] =
- a[ ] =
▶ 使用私有变量估计 π 的值
- #include <stdio.h>
- #include <stdlib.h>
- #include <omp.h>
- const int thread = , count = ;
- int main0(int argc, char* argv[])// 一般方法,使用局部变量
- {
- int i, threadReal;
- double sum;
- if (argc > && *argv[] > ''&& *argv[] < '')
- threadReal = atoi(argv[]);
- else
- threadReal = thread;
- sum = 0.0;
- #pragma omp parallel for num_threads(threadReal) reduction(+ : sum)
- for (i = ; i < count; i++)
- {
- double sign = (i % ? -1.0 : 1.0);
- sum += sign / ( * i + );
- }
- printf("π = %.10f\n", sum * );
- getchar();
- return ;
- }
- int main1(int argc, char* argv[])// 将已经声明了的 sign 作为私有变量
- {
- int i, threadReal;
- double sign, sum;
- if (argc > && *argv[] > ''&& *argv[] < '')
- threadReal = atoi(argv[]);
- else
- threadReal = thread;
- sum = 0.0;
- #pragma omp parallel for num_threads(threadReal) reduction(+ : sum) private(sign)
- for (i = ; i < count; i++)
- {
- sign = (i % ? -1.0 : 1.0);
- sum += sign / ( * i + );
- }
- printf("π = %.10f\n", sum * );
- getchar();
- return ;
- }
- int main2(int argc, char* argv[])// 使用 default(none) 子句,然后明确规定每个变量的作用域
- {
- int i, threadReal;
- double sign, sum;
- if (argc > && *argv[] > ''&& *argv[] < '')
- threadReal = atoi(argv[]);
- else
- threadReal = thread;
- sum = 0.0;
- #pragma omp parallel for num_threads(threadReal) reduction(+ : sum) default(none) private(i, sign) shared(count)// 多个变量用逗号隔开
- for (i = ; i < count; i++)
- {
- sign = (i % ? -1.0 : 1.0);
- sum += sign / ( * i + );
- }
- printf("π = %.10f\n", sum * );
- getchar();
- return ;
- }
● 输出结果
- π = 3.1415826536
OpenMP 简单的规约的更多相关文章
- 基于GCC的openMP学习与测试(2)
一.openMP简单测试 1.简单测试(1) #include<omp.h> #include<time.h> #include<iostream> using n ...
- 基于GCC的openMP学习与测试
(一).openMP简述 Open Multiprocessing (OpenMP) 框架是一种功能极为强大的规范,可以帮助您利用 C.C++ 和 Fortran 应用程序中的多个核心带来的好处,是基 ...
- CUDA01 - 硬件架构、warp调度、指令流水线和cuda并发流
这一部分打算从头记录一下CUDA的编程方法和一些物理架构上的特点:从硬件入手,写一下包括线程束的划分.流水线的调度等等微结构的问题,以及这些物理设备是如何与软件对应的.下一部分会写一下cuda中的几种 ...
- 应用OpenMP的一个简单的设计模式
小喵的唠叨话:最近很久没写博客了,一是因为之前写的LSoftmax后馈一直没有成功,所以在等作者的源码.二是最近没什么想写的东西.前两天,在预处理图片的时候,发现处理200w张图片,跑了一晚上也才处理 ...
- OpenMP的简单使用教程
转自:http://binglispace.com/2015/01/09/openmp-intro/ OpenMP的简单使用教程 今天有幸参加了一个XSEDE OpenMP的workshop讲座,真是 ...
- 并行编程OpenMP基础及简单示例
OpenMP基本概念 OpenMP是一种用于共享内存并行系统的多线程程序设计方案,支持的编程语言包括C.C++和Fortran.OpenMP提供了对并行算法的高层抽象描述,特别适合在多核CPU机器上的 ...
- VS2010+OpenMP的简单使用
OpenMP是把程序中的循环操作分给电脑的各个CPU处理器并行进行.比如说我要循环运行100次,我的电脑有两个处理器,那OpenMP就会平均分给两个处理器并行运行,每个处理器运行50次.使用方法 1. ...
- 基于OpenMP的C++并行编程简单示例
示例要求:在整数A和B之间找到符合条件的值X,使f(X)=C. 示例代码(需要在VS中开启OpenMP支持): #include<iostream> #include<time.h& ...
- [OpenMP] 并行计算入门
OpenMP并行计算入门 个人理解 OpenMP是一种通过共享内存并行系统的多处理器程序设计的编译处理方案,通过预编译指令告诉编译器哪些代码块需要被并行化,通过拷贝代码块实现并行程序.对于循环的并行化 ...
随机推荐
- 递归--练习9--noi8758 2的幂次方表示
递归--练习9--noi8758 2的幂次方表示 一.心得 找准子问题就好 二.题目 8758:2的幂次方表示 总时间限制: 1000ms 内存限制: 65536kB 描述 任何一个正整数都可以用 ...
- JSP 文件上传
JSP 文件上传 JSP可以通过HTML的form表单上传文件到服务器. 文件类型可以是文本文件.二进制文件.图像文件等其他任何文档. 创建文件上传表单 接下来我们使用HTML标签来创建文件上传表单, ...
- 通过VNC连接远程服务器,然后登陆服务器上的虚拟机,出现键盘输入问题的解决方法
前几天由于要在服务器上装一个虚拟机,然后就选择了vmware workstation,装好之后,进入虚拟机中的centOS系统,发现键盘上的Cpas Lock键不起作用,按下之后还是输入小写,而且按住 ...
- linux提权辅助工具(二):linux-exploit-suggester-2.pl
来自:https://github.com/jondonas/linux-exploit-suggester-2/blob/master/linux-exploit-suggester-2.pl #! ...
- web前端开发常用的几种图片格式及其使用规范
首先,在正式说图片格式之前,咱们先说一些额外的东西. 矢量图与位图 矢量图是通过组成图形的一些基本元素,如点.线.面,边框,填充色等信息通过计算的方式来显示图形的.一般来说矢量图表示的是几何图形,文件 ...
- prisma 集成tidb 安装试用
以前官方提供的ansible 的脚本,现在有了docker的版本,可以方便测试使用 实际完整配置参考 https://github.com/rongfengliang/prisma-tidb 安装ti ...
- ORA-01033: ORACLE initialization or shutdown in progress --手动删除表空间 DBF 后无法登陆问题
进入CMD,执行set ORACLE_SID=fbms,确保连接到正确的SID: 2.执行sqlplus "/as sysdba" SQL>shutdown immediat ...
- <script type="text/template">是干什么的,为什么要把html写在js中? 这是什么编程语言风格,都能这样用吗?
这一段存放了一个模板.在js里面,经常需要使用js往页面中插入html内容.比如这样: var number = 123; $('#d').append('<div class="t& ...
- eclipse中点不出来提示
当在用eclipse或是myeclipse时,可能会遇到不能自动提示,就是当你用到点的时候,后面不会出现相关的提示信息.这时,解决方法如下 : 1.菜单window->Preferences-& ...
- FastAdmin 学习线路 (2018-06-09 更新)
FastAdmin 学习线路 以下为常规线路,非常规可跳过. FastAdmin 学习线路 基础 HTML CSS DIV Javascript 基础 jQuery php 基础 对象 命名空间 进阶 ...