BlueRoseNote/02-Note/读书笔记/深入应用C++11代码优化与工程级应用/深入应用c++11代码优化与工程级应用第十五章.md
2023-06-29 11:55:02 +08:00

3.1 KiB
Raw Blame History

使用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);
		}
	};
}