博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
concurrency runtime学习笔记之二:并行
阅读量:4677 次
发布时间:2019-06-09

本文共 3108 字,大约阅读时间需要 10 分钟。

并行依赖的是底层多线程处理机制,线程的创建和销毁,还有线程间的同步问题常常令人望而生畏。concrrency runtime提供的并行库Parallell Patterns Library (PPL)提高了线程处理机制的抽象级别,让C++多线程并行变得异常的简单。

 

先看一下构架:

Concurrency Runtime Architecture

应该很清楚了,PPL处于应用程序和线程处理机制之间。

 

再来看一个常规的例子,计算斐波那契数列:

#include 
#include
#include
using namespace std;using namespace Concurrency;// Computes the nth Fibonacci number.int fibonacci(int n){ if(n < 2) return n; return fibonacci(n-1) + fibonacci(n-2);}// Calls the provided work function and returns the number of milliseconds // that it takes to call that function.template
__int64 time_call(Function&& f){ __int64 begin = GetTickCount(); f(); return GetTickCount() - begin;}int _tmain(int argc, _TCHAR* argv[]){ __int64 elapsed; // An array of Fibonacci numbers to compute. array
a = { 24, 26, 41, 42 }; // Use the for_each algorithm to compute the results serially. elapsed = time_call([&] { size_t sum = 0; for_each (a.begin(), a.end(), [&](int n) { sum += fibonacci(n); }); wcout << sum << endl; }); wcout << L"serial time: " << elapsed << L" ms" << endl; return 0;}

如果调用并行算法,就把for_each换成parallel_for_each,不过要注意在一个并行循环体内,对共享资源的操作只允许读不允许写,所以要实现累加的话需要用到互斥对象   

elapsed = time_call([&]    {      critical_section cs;      size_t sum = 0;      parallel_for_each (a.begin(), a.end(), [&](int n)      {         cs.lock();         sum += fibonacci(n);         cs.unlock();      });      wcout << sum << endl;   });   wcout << L"parallel time: " << elapsed << L" ms" << endl;

更好的办法是用 来协调线程间的冲突:

elapsed = time_call([&]    {      combinable
sum; parallel_for_each (a.begin(), a.end(), [&](int n) { sum.local() += fibonacci(n); }); size_t fibsum = sum.combine(std::plus
()); wcout << fibsum << endl; }); wcout << L"parallel time: " << elapsed << L" ms" << endl;

取消并行循环要将并行算法包含在一个任务组中,并用取消这个任务组,因为从构架上来说,并行库是在task scheduler模块之下的,所以取消机制是自上而下的,也就是说取消的是整个任务组,看程序:

structured_task_group tasks;   tasks.run_and_wait([&]   {      parallel_for_each(a.begin(), a.end(), [&](int n)       {         if (n == 41)         {
tasks.cancel(); } }); });

以上是parallel_for_each算法的大致应用,parallel_for算法用法大同小异,parallel_invoke用的较少。尽管concurrency runtime封装并优化了多线程调用,但是线程调用的开销仍是存在的,运用时要考虑下是否值得。一般来说,计算密集型的应用比较合适,比方说图象处理算法,而对于小型轻量循环体就弊大于利了。

 

 

--------------------------------------------------------------------

附一道面试题:一个人走楼梯,可以一次走1层,也可以走2层,也可以走3层,问n层楼梯有多少种走法。

解:

1----> 1
1阶楼梯的爬法总共为: 1
2----> 1 1
2----> 2
2阶楼梯的爬法总共为: 2
3----> 1 1 1
3----> 1 2
3----> 2 1
3----> 3
3阶楼梯的爬法总共为: 4
4----> 1 1 1 1
4----> 1 1 2
4----> 1 2 1
4----> 1 3
4----> 2 1 1
4----> 2 2
4----> 3 1
4阶楼梯的爬法总共为: 7

5----> 1 1 1 1 1
5----> 1 1 1 2
5----> 1 1 2 1
5----> 1 1 3
5----> 1 2 1 1
5----> 1 2 2
5----> 1 3 1
5----> 2 1 1 1
5----> 2 1 2
5----> 2 2 1
5----> 2 3
5----> 3 1 1
5----> 3 2
5阶楼梯的爬法总共为: 13

看下规律,大概就是个fibonacci数列,f(n) = f(n-1) + f(n-2) + f(n-3) ,其中f(1)=1,f(2)=2,f(3)=4

 

转载于:https://www.cnblogs.com/xfu123/archive/2012/04/21/2460820.html

你可能感兴趣的文章
python会缓存小的整数和短小的字符
查看>>
格网与四叉树索引
查看>>
Linux网卡配置文件路径是什么?要使服务器上外网,必须满足的条件有哪些?需要配置什么?...
查看>>
多张照片拍摄、图片浏览
查看>>
html(5) css
查看>>
微信小程序时间戳 页面中时间戳转成自己需要的格式(支持列表循环等)
查看>>
CSS笔记2
查看>>
Azure Web连接到Azure MySql Db
查看>>
Python2快速入门教程,只需要这十五张图片就够了!
查看>>
cdoj 1131 男神的礼物 区间dp
查看>>
美白、磨皮、搞笑图片处理
查看>>
C/C++代码覆盖工具gcov与lcov入门
查看>>
[12/11/19] 折半&倍增思想学习笔记
查看>>
关于endnote与word或wps关联的问题
查看>>
分块打表
查看>>
uva 297 - Quadtrees
查看>>
数组练习3 求最大连通子数组的和
查看>>
hdu_2111_Saving HDU(贪心)
查看>>
hdu_5753_Permutation Bo(找规律)
查看>>
两种分页方案
查看>>