132 lines
3.1 KiB
Markdown
132 lines
3.1 KiB
Markdown
|
### 使用c++11开发一个轻量级的并行task库
|
|||
|
#### 15.1 TBB的基本用法
|
|||
|
#### 15.1.1 TBB概述
|
|||
|
TBB 是inter用标准c++写的一个开源的并行计算库,它的目的是提升数据并行计算的能力。主要功能如下:
|
|||
|
1. 并行计算
|
|||
|
2. 任务调度
|
|||
|
3. 并行容器
|
|||
|
4. 同步原语
|
|||
|
5. 内存分配器
|
|||
|
#### 15.1.2 TBB并行算法
|
|||
|
1. parallel_for:以并行的方式遍历一个区间
|
|||
|
2. parallel_do和parallel_for_each:将算法用于一个区间
|
|||
|
3. parallel_reduce:并行汇聚
|
|||
|
4. parallel_pipeline:并行的管道过滤器
|
|||
|
5. parallel_sort和parallel_invoke:并行排序和调和
|
|||
|
#### 15.1.3 TBB的任务组
|
|||
|
```
|
|||
|
tbb::task_group g;
|
|||
|
g.run([]{task();});
|
|||
|
g.run([]{task();});
|
|||
|
g.run([]{task();});
|
|||
|
g.wait();
|
|||
|
```
|
|||
|
#### 15.2 PPL的基本用法
|
|||
|
两者差异:
|
|||
|
1. parallel_reduce的原型有些不同。
|
|||
|
2. PPL中没有parallel_pipeline接口
|
|||
|
3. TBB的task没有PPL的task强大,PPL的task可以链式连续执行,还可以组合任务,而TBB的task不行。
|
|||
|
#### 15.5 TaskCpp的任务
|
|||
|
#### 15.5.1 task的实现
|
|||
|
基于task的并行编程模型最基本的执行单元是task,一个task就代表了一个要执行的任务。外部只需要简单调用接口就可以创建task并且执行,另一个细节就是异步执行。
|
|||
|
```
|
|||
|
template<typename T>
|
|||
|
class Task;
|
|||
|
|
|||
|
template<typename R, typename...Args>
|
|||
|
class Task<R(Args...)>
|
|||
|
{
|
|||
|
std::function<R(Args...)> m_fn;
|
|||
|
|
|||
|
public:
|
|||
|
typedef R return_type;
|
|||
|
|
|||
|
template<typename F>
|
|||
|
auto Then(F&& f)//->Task<typename std::result_of<F(R)>::type(Args...)>
|
|||
|
{
|
|||
|
typedef typename std::result_of<F(R)>::type ReturnType;
|
|||
|
auto func = std::move(m_fn);
|
|||
|
return Task<ReturnType(Args...)>([func, &f](Args&&... args)
|
|||
|
{
|
|||
|
std::future<R> lastf = std::async(func, std::forward<Args>(args)...);
|
|||
|
return std::async(f, lastf.get()).get();
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
Task(std::function<R(Args...)>&& f) :m_fn(std::move(f)){}
|
|||
|
Task(std::function<R(Args...)>& f) :m_fn(f){}
|
|||
|
|
|||
|
~Task()
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
void Wait()
|
|||
|
{
|
|||
|
std::async(m_fn).wait();
|
|||
|
}
|
|||
|
|
|||
|
template<typename... Args>
|
|||
|
R Get(Args&&... args)
|
|||
|
{
|
|||
|
return std::async(m_fn, std::forward<Args>(args)...).get();
|
|||
|
}
|
|||
|
|
|||
|
std::shared_future<R> Run()
|
|||
|
{
|
|||
|
return std::async(m_fn);
|
|||
|
}
|
|||
|
};
|
|||
|
```
|
|||
|
#### 15.5.2 task的延续
|
|||
|
```
|
|||
|
#include <functional>
|
|||
|
namespace Cosmos
|
|||
|
{
|
|||
|
template<typename T>
|
|||
|
class Task;
|
|||
|
|
|||
|
template<typename R, typename...Args>
|
|||
|
class Task<R(Args...)>
|
|||
|
{
|
|||
|
std::function<R(Args...)> m_fn;
|
|||
|
|
|||
|
public:
|
|||
|
typedef R return_type;
|
|||
|
|
|||
|
template<typename F>
|
|||
|
auto Then(F&& f)//->Task<typename std::result_of<F(R)>::type(Args...)>
|
|||
|
{
|
|||
|
typedef typename std::result_of<F(R)>::type ReturnType;
|
|||
|
auto func = std::move(m_fn);
|
|||
|
return Task<ReturnType(Args...)>([func, &f](Args&&... args)
|
|||
|
{
|
|||
|
std::future<R> lastf = std::async(func, std::forward<Args>(args)...);
|
|||
|
return std::async(f, lastf.get()).get();
|
|||
|
});
|
|||
|
}
|
|||
|
|
|||
|
Task(std::function<R(Args...)>&& f) :m_fn(std::move(f)){}
|
|||
|
Task(std::function<R(Args...)>& f) :m_fn(f){}
|
|||
|
|
|||
|
~Task()
|
|||
|
{
|
|||
|
}
|
|||
|
|
|||
|
void Wait()
|
|||
|
{
|
|||
|
std::async(m_fn).wait();
|
|||
|
}
|
|||
|
|
|||
|
template<typename... Args>
|
|||
|
R Get(Args&&... args)
|
|||
|
{
|
|||
|
return std::async(m_fn, std::forward<Args>(args)...).get();
|
|||
|
}
|
|||
|
|
|||
|
std::shared_future<R> Run()
|
|||
|
{
|
|||
|
return std::async(m_fn);
|
|||
|
}
|
|||
|
};
|
|||
|
}
|
|||
|
```
|