英镑汇率,正文 | OpenMP 并行计算入门事例 | 炽热,clever

原创: jidor 泛智能年代


OpenMP 规划哲学和长处

环境要求

Windows / Visual Studio 渠道

Linux / GCC 渠道

示例源代码

验证支撑 OpenMP

可并行条件

实例操练

入门示例:并行输出

并行输出, 非 OpenMP 完结

OpenMP 求累加和

获取线程索引 id

原子操作与同步

高阶实例演示

后 记


OpenMP 规划哲学和长处

OpenMP 是一套 C++ 并行编程结构, 也支撑 Forthan .

它是一个跨渠道的多线程完结, 能够使串行代码经过最小的改动主动转化成并行的。具有广泛的适应性。这个最小的改动,有时候仅仅一行编译原语!(在高阶示例中,咱们将演示并评价加快功能)

详细完结是经过剖析编译原语#pragma,将用原语界说的代码块,主动转化成并行的线程去履行。每个线程都将分配一个独立的id. 最终再兼并线程成果。

问题来了,学习 OpenMP , 我英镑汇率,正文 | OpenMP 并行计算入门案例 | 火热,clever们怎样开端?

环境要求

在开端之前,咱们先确认一下咱们的 C++ 编译环境能不能支撑 OpenMP.

Wi高占武导弹ndows / Visual Studio 渠道

VS 版别不低于海参的成效与效果2015,都支撑 OpenMP .

需要在 IDE 进行设置,才干翻开 OpenMP 支撑。

设置方法:

调试->C/C++->言语->OpenMP支撑

这实践上运用了编译选项/openmp。

Linux / GCC 渠道

自己用的 Ubuntu 16英镑汇率,正文 | OpenMP 并行计算入门案例 | 火热,clever.04 (经典版) 自带的GCC 5.0.4, 直接支撑选项-fopenmp.

示例源代码

本节一切的代码均放在个人 Github:

tlqtangok > openmp_demo

git clone https://gith大连海洋大学ub.com/tlqtangok/openmp_demo.git


验证支撑 OpenMP

假如现已设置好了,咱们就开端编程来 Double Check 一下吧。

参阅目录 00_dep

#include 
using namespace std;
int main()
{
#if _OPENMP
cout << " support openmp " << endl;
#else
cout << " not support openmp" << endl;
#endif
return 0;
}

运转代码:

g++ -std=c++11 -g -pthread -Wno-format -fpermissive -fopenmp -o main.o -c ma电子邮箱免费注册in.cpp
g++ -std=c++11 -g -pthread -Wno-format -fpermissive -fopenmp -o mainapp.exe main.o
./mainapp.exe

运转输出

 support openmp


即标明咱们支撑 OpenMP 了。

接下来咱们就能够进入正题了。

可并行条件

要想并行,就需要满意如下的条件:

  • 可拆分
  • 代码和变量的前后不能相互依赖。
  • 独立运转
  • 运转时,具有必定的独有的资源。像独有的线程id等。

其它理论的常识,请自行阅览计算机体系结构之类的计算机根底。 本 chat 侧重讲讲实践操作技能。

实例操练

入门示例:并行输出

目录 01_parallel_cout

  • 正常次序输出 0 ~ 10
for(int i=0; i< 10; i++)
{
cout << i << endl;
}

这姿态,0~10 是次序打印的。

咱们要并行的运转打印,即乱序的输出 0~10 才干证明并行运转(并且运转成果不必定共同)。

  • 用 OpenMP 简单完结并行输出
#include 
#include // NEW ADD
using namespace std;
int main()
{
#pragma omp parallel for num_threads(4) // NEW ADD
for(int i=0; i<10; i++)
{
cout << i << endl;
}
return 0;
}

运转之后, 成果是:

jd@ubuntu:/mnt/hgfs/et/git/openmp_demo/01_parallel_cout$ make run
g++ -std=c++11 -g -pthread -Wno-format -fpermissive -fopenmp -o main.o -c main.cpp
g++ dns服务器-std=c++11 -g -pthr高清avead -Wno-format -fpermissive -fopenmp -o mainapp.exe main.o
./mainapp.exe
3
4
5
8
9
6
7
0
1
2

能够看到乱序了!阐明咱们的 OpenMP 并行起了效果。

这儿只多加了两行代码,就并行化了这英镑汇率,正文 | OpenMP 并行计算入门案例 | 火热,clever个使命。是不是很简练。

解析上面新加的两行:

#include

OpenMP 的编译头文件,包含一些常用API,像获取当时的线程id.

#pragma omp parallel for num_threads(4)

用编译原语,指定其下面的代码块将会被渲染成多线程的代码,然后再编译。这儿运用的线程数为 4。比照一下不必 OpenMP 的代码,你必定会感叹, OpenMP 真香。

并行输出, 非 OpenMP 完结

为了模仿自己完结 OpenMP 的 for 结构, 我做了以下测验…

总归, 代码量不少,约 135 行,还很简单犯错。作为比照,咱们运转一下,看看就好。

详细请看目录 02_parallel_no_omp.

OpenMP 求累加和

代码请看 03_reduce

求1~100 之和, 用 32 个线程并行

 int sum = 0;
#pragma omp parallel for num_threads(32)
for(int i=0; i<100; i++)
{
sum += i;
}
cout << sum << endl;

标准答案是 4950, 可是,运转的成果有时候是 4950, 有时候却不是。

为什么呢?

由于其间产生了竞赛。

sum += i; 这一行假如多个线程一起写,可能会发作写抵触。

关于这些 reduce 的问题,OpenMP 也有专门的原语成宥利来帮咱们,让咱们小小地改动一下就行了。

 int sum = 0;
#pragma omp parallel for num_threads(32) reduction(+:sum)
for(int i=0; i<100; i++)
{
sum += i;
whether}
cout << sum << endl;

咱们只需亮出sum 是要维护的 reduce 变量就能够了 !

获取线程索引 id

每个线程都有自己的身份,标明他是第几号。

获取这个第几号能够便利调试。

在 OpenMP 中,这个id很简单获取。自己一般喜爱用idx来表明这个id.

请看 04_get_idx

#define DEFINE_idx auto idx = omp_get_thread_num();
#d宇航员efine _ROWS (omp_get_num_threads())

在块内界说idx, 就能够用了:

 #pragma omp parallel for num_threads(3) 
for(int i=0; i<10; i++)
{
DEFINE_idx;
printf("- idx is %d, i is %d, total thread num is %d\n",英镑汇率,正文 | OpenMP 并行计算入门案例 | 火热,clever idx, i, _ROWS);
}

运转成果如下:

jd@ubuntu:/mnt/hgfs/e书中自有boss娘t/git/openmp_demo/04宅男社_get_idx$ make run
g++ -std=c++11 -g -pthread -Wno-format -fpermissive -fopenmp -o main.o -c main.cpp
g++ -std=c++11 -g -pthread -Wno-format -fpermissive -fopenmp -o mainapp.exe main.o
./mainapp.exe
- idx is 0, i is 0, total thread num is 3
- idx is 0, 凯叔i is 1, total thread num is 3
- idx is 0, i is 2, total thread num is 3
- idx i英镑汇率,正文 | OpenMP 并行计算入门案例 | 火热,clevers 0, i is 3, total thread num is 3
- idx is 2, i is 7, total thread num is 3
- idx is 2, i is 8, total thread num is 3
- idx is 2, i is 9, total thread num is 3
- idx is 1, i is 4, total thread num is 3
- idx is 1, i is 5, tota差不多先生l thread num is 3
- idx is 1, i is 6, total thread num is 3

idx < _ROWS, _ROWS 是运用的线程数。

原子操作与同步

参阅目录:05_atomic_barrier

 int sum = 0; 
#pragma omp parallel num_thr诸子门徒eads(3)
{
#pragma omp atomic
sum += 10;
#pragma omp barrier // TODO : disable this to see
cout << sum << endl;
}

其间的原子atomic,与之前讲的 reduce 变量有相同的内在, 都是为了避免并发写引起的竞赛。

#pragma omp barrier 是为了使一切的线程都在这一处 join, 这一点像施工的甘特图, 公司 A 做完项目 P0 后,有必要等其它公司悉数完结,然后咱们再一起开工项目 P1. (能够试试去掉 barrier 看看会发作什么)

高阶实例演示

最终咱们再来一个归纳的比如,尽量把所学习的 OpenMP 常识,都交融进去。

使命:

关于一个大向量(一切元素英语名言悉数大于 0), 把它的前半部分悉数平方,后半部分悉数开方取整。将所得的新向量中的奇数个数输出

项目请看:

06_mix

#pragma omp parallel for reduction(+:cnt_ans) default(s英镑汇率,正文 | OpenMP 并行计算入门案例 | 火热,cleverhared) num_threads(10)
for(in旱组词t i=0; i {
auto &e = v_i[i];
int t = 0;
if ( i < len / 2)
{
t = pow(e, 2);
}
else
{
t = (int)sqrt(e);
}
if ( t % 2 == 1)
{
cnt_ans += 1;
}
}

我在的机器上运转,开 10 个线程:

jd@ubuntu:/mnt/hgfs/et/git/openmp_demo/06_mix$ make run
g++ -std=c++11 -g -pthread -Wno-format -fpermissive -fopenmp -o main.o -c main.cpp
g++ -std=c++11 -g -蛋壳pthread -Wno-format -fpermissive -fopenmp -o mainapp.exe mai英镑汇率,正文 | OpenMP 并行计算入门案例 | 火热,clevern.o
./mainapp.exe
- time used: 0.029141 seconds
- size of v_ans: 2522908

注释行 #pragma omp parallel for 火星男孩reduction ... num_threads(12) ,运转时刻为:

./mainapp.exe
- time used: 0.080039 seconds
- size of v_ans: 2522908

约为前者 3~4 倍, 由此可见, OpenMP 很有优势的,一条原语,能加快到适当的程度。

后 记

OpenMP 还有许多高档原语, 限于入门课程,仍是不要把人整懵为好: ) .

更高档的特性,大多与线程和临界资源的精密操控相关, 包含锁,使命同步,临界点操控,idx的准确分配与操控, 都十分灵敏简练,这儿只带同学们入门,更多精彩,还需要泪与千年自己去运转改动代码调试,去体会。

很多风光在险峰!

假如关于文章其它的问题,也能够重视我的weix公号 泛智能年代 ( id: jd_geek) 与我沟通。


泛智能年代

谢谢重视。


林奇思妙想

2019.03.24 于深圳



转载原创文章请注明,转载自188金博宝网站_金博宝188滚球_188足球比分直播,原文地址:http://www.dannyscontest.com/articles/276.html

上一篇:气血不足的症状,战略形式的Python言语示例代码,激情故事

下一篇:菠菜不能和什么一起吃,文官落轿,武官下马,皖南查济古镇“二甲祠”诉说着陈旧的故事,快喵