▶ 简单的计算和规约

● 第一种方法,将全局和的指针传入工作函数中进行加和,使用 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 简单的规约的更多相关文章

  1. 基于GCC的openMP学习与测试(2)

    一.openMP简单测试 1.简单测试(1) #include<omp.h> #include<time.h> #include<iostream> using n ...

  2. 基于GCC的openMP学习与测试

    (一).openMP简述 Open Multiprocessing (OpenMP) 框架是一种功能极为强大的规范,可以帮助您利用 C.C++ 和 Fortran 应用程序中的多个核心带来的好处,是基 ...

  3. CUDA01 - 硬件架构、warp调度、指令流水线和cuda并发流

    这一部分打算从头记录一下CUDA的编程方法和一些物理架构上的特点:从硬件入手,写一下包括线程束的划分.流水线的调度等等微结构的问题,以及这些物理设备是如何与软件对应的.下一部分会写一下cuda中的几种 ...

  4. 应用OpenMP的一个简单的设计模式

    小喵的唠叨话:最近很久没写博客了,一是因为之前写的LSoftmax后馈一直没有成功,所以在等作者的源码.二是最近没什么想写的东西.前两天,在预处理图片的时候,发现处理200w张图片,跑了一晚上也才处理 ...

  5. OpenMP的简单使用教程

    转自:http://binglispace.com/2015/01/09/openmp-intro/ OpenMP的简单使用教程 今天有幸参加了一个XSEDE OpenMP的workshop讲座,真是 ...

  6. 并行编程OpenMP基础及简单示例

    OpenMP基本概念 OpenMP是一种用于共享内存并行系统的多线程程序设计方案,支持的编程语言包括C.C++和Fortran.OpenMP提供了对并行算法的高层抽象描述,特别适合在多核CPU机器上的 ...

  7. VS2010+OpenMP的简单使用

    OpenMP是把程序中的循环操作分给电脑的各个CPU处理器并行进行.比如说我要循环运行100次,我的电脑有两个处理器,那OpenMP就会平均分给两个处理器并行运行,每个处理器运行50次.使用方法 1. ...

  8. 基于OpenMP的C++并行编程简单示例

    示例要求:在整数A和B之间找到符合条件的值X,使f(X)=C. 示例代码(需要在VS中开启OpenMP支持): #include<iostream> #include<time.h& ...

  9. [OpenMP] 并行计算入门

    OpenMP并行计算入门 个人理解 OpenMP是一种通过共享内存并行系统的多处理器程序设计的编译处理方案,通过预编译指令告诉编译器哪些代码块需要被并行化,通过拷贝代码块实现并行程序.对于循环的并行化 ...

随机推荐

  1. 使用80percent开发rails程序:gem的了解。(kaminari)

    学习目的: 对一些主要的gem进行学习了解基本功能: 作者的一些答复:(链接) 关于安全配置: 对于配置文件, 安全仅有一点: 不要提交任何敏感信息到服务端. 所以 rails-template 是添 ...

  2. 安装Ubuntu版本linux过程中没有提示设置root用户密码问题的解决办法

    原来ubunto不提倡设置root用户,系统安装成功后,root密码是随机的,那么在这种情况下如何得到root权限呐,具体方法如下: 终端中输入:sudo passwd root 此时重新设置原登录用 ...

  3. 位于/var/log目录下的20个Linux日志文件

    位于/var/log目录下的20个Linux日志文件[译] from:http://buptguo.com/2014/01/16/linux-var-log-files/ 原文地址:20 Linux ...

  4. 使用Pandas: str.replace() 进行文本清洗

    前段时间参加了Kaggle上的Mercari Price Suggestion Challenge比赛,收获良多,过些时候准备进行一些全面的总结,本篇文章先谈一个比赛中用到的小技巧. 这个比赛数据中有 ...

  5. Beta阶段第2周/共2周 Scrum立会报告+燃尽图 12

    作业要求[https://edu.cnblogs.com/campus/nenu/2018fall/homework/2411] 版本控制:https://git.coding.net/liuyy08 ...

  6. JS在项目中用到的AOP, 以及函数节流, 防抖, 事件总线

    1. 项目中在绑定事件的时候总想在触发前,或者触发后做一些统一的判断或逻辑,在c#后端代码里,可以用Attribute, filter等标签特性实现AOP的效果,可是js中没有这种用法,归根到本质还是 ...

  7. Django 之 用redis存储session

    方案I: 1. 安装 django-redis liuqian@ubuntu:~$ pip install django-redis dango-redis 官方文档:http://niwinz.gi ...

  8. iOS-----使用AddressBookUI管理联系人

    使用AddressBookUI管理联系人 iOS SDK为管理地址簿提供的视图控制器位于AddressBookUI框架内.总结来说,AddressBookUI框架提供了如下特殊的视图控制器. ABPe ...

  9. 20155322 2016-2017-2 《Java程序设计》第6周学习总结

    20155322 2016-2017-2 <Java程序设计>第6周学习总结 教材学习内容总结 第六周学习的主要内容是课本的第十第十一章: 第十章介绍的是输入.输出,Java中的流分为两种 ...

  10. CF1143C Queen

    CF1143C Queen 开始想大力维护 \(bfs\) 序+数据结构解决,但 \(bfs\) 序的变化不太好推. 换了一个思路,注意到删除一个点后,原来可以被删除的点仍然可以被删除,原来不能被删除 ...