一、HetComputeSDK基本功能介绍
1、HetComputeSDK开发组件为高通平台提供了硬件处理器控制接口,用于控制CPU、GPU、DSP硬件执行指定的计算任务。
2、HetComputeSDK开发组件在用户层开放全部的硬件控制权限:
a、通过提供一个并行程序模型,允许程序员在他们的应用中使用并发操作。HetCompute强大的抽象建立了一个动态并发基 础,这个设计减轻了并行计算编程的负担。在上层,HetCompute提供一组并行编程模式,这些模式捕获了许多现有的并行 构 建块,增加数据流和取消任务添加为第一类原语,以提高程序员的工作效率。
b、通过无缝集成heterogeneous直行进入一个并发行的任务图谱,并且消除在不同设备上执行的内核之间管理数据传输和显式数据复制的负担。在底层,HetCompute为任务窃取和优化电源提供了最先进的算法,使其能够隐藏硬件特性,从而允许开发便携式应用程序。另外,HetCompute旨在支持到异构执行单元的动态映射。此外,专业程序员可以通过精心设计的属性和指令系统来执行,该系统向运行实时系统提供有关HetCompute用作构建块的模式、任务和缓冲区的附加语义信息。
c、通过嵌入C++编程模型,并且提供一个C++库的API。C++对于程序员来说是熟悉的,并且需要功能是面向性能的开发,因此程序员很容易快速地提取抽象。嵌入式C++还允许对现有应用程序的增量开发,因为HetCompute与现有的库(如pthreads和OpenGL)交互操作。
3、HetCompute运行在实时操作系统的顶层,运行的实时系统将在SOC所有的可用计算资源上执行并发应用程序。HetCompute运行的实时系统本质上是线程、地址空间和设备的资源管理器。它建立在一组最先进的算法之上,使程序员不必显式地管理这些资源,并为hetcompute执行模型提供最佳性能。
4、HetCompute也提供了并行模式和并发抽象及其执行模型。开发者可以根据应用实际使用环境设计适合的工作模式
5、HetComputeSDK架构图
二、HetComputeSDK任务创建机制
1、HetCompute提供多种模板为了适配用户几种使用场景
a、在group中创建和执行HetComputeSDK任务
1) template<typename Code, typename...Args>
void hetcompute::group::launch(Code&& code, Args&& ...args)
2) template<typename Code, typename...Args>
void hetcompute::group::launch(do_not_collapse_t, Code&& code, Args&& ...args)>,在组中启动任务是在hetcompute 中创建和执行任务的最快方法。在一个group中启动,可以简化任务指针的生命周期维护,因为运行时会处理它。如果任务 逻辑上属于其他任务,请考虑创建组并在组中启动任务。
b、创建一个HetCompute的任务和执行
1) template<typename Code, typename...Args>
collapsed_task_type<Code> hetcompute::launch(Code&& code, Args&& ...args
2) template<typename Code, typename...Args>
non_collapsed_task_type<Code> hetcompute::launch(do_not_collapse_t, Code&& code, Args&& ...args)>,如果任务 不是在组中,那么创建和执行一个任务润徐程序直接将任务送到实时系统中执行。实时系统之岛任务没有任何前置任 务,随时准备执行任务。
c、创建一个HetCompute任务,但不执行
1) template<typename ReturnType, typename... Args>
hetcompute::task_ptr<ReturnType> hetcompute::create_value_task(Args&& ...args)
2) template<typename Code, typename... Args>
collapsed_task_type<Code> hetcompute::create_task(Code&&, Args&&...)
3) template<typename Code, typename... Args>
non_collapsed_task_type<Code> hetcompute::create_task(do_not_collapse_t, Code&&, Args&&...),使用create_task 方式创建一个任务并且返回一个指针给任务。任务尚未准备好启动,可以设置依赖项(将此任务作为任务图的一部 分)。实时系统在任务执行时保证指针的有效性。但是,由于程序有一个指向它的指针,该指针的生命周期也会影响任 务在系统中的维护时间。建议在完成任务后重置指针。
2、创建HetCompute任务的集中组成部分
a、任务类型:collapsed或者non-collapsed
默认状态下,折叠任务被创建。否则,通过hetcompute::do_not_collapse强制创建非折叠任务。
b、计算模板方法中的任务,是Code&& code,HetCompute支持以下计算结构并封装在任务中。
1) C++基本功能块,例如:lambda表达式,函数实例或者函数指针。
2) HetCompute Kernels。
3) HetCompute Patterns。
c、在模板中绑定到任务的参数,例如:Args&&… args。如果任务的计算构造采用了一些参数,则可以在创建任务时将这些参数绑定到任务。参数绑定也可以在创建任务后发生(hetcompute::task<ReturnType(Args...)>bind_all),但是在程序执行前,必须要做这些工作。
3、第一个创建组模板,创建一个任务并返回指向它的指针(hetcompute::task_ptr<...>)。
a、任务指针是根据任务中封装的计算结构的类型键入的。例如,下面的代码创建三个hetcompute任务:
1) auto t1 = hetcompute::create_task([&] {i ++;});
2) auto t2 = hetcompute::create_task([&] {return 42;});
3) auto t3 = hetcompute::create_task([&] (bool b, float f){return b ? int(f) : 0;});
注:The type of t1 is hetcompute::task_ptr<>.
The type of t2 is hetcompute::task_ptr<int>.
The type of t3 is hetcompute::task_ptr<int(bool, float)>.
b、task_ptr的类型决定了在任务中指针的操作模式:
1) hetcompute::task_ptr<>仅仅能够建立控制依赖,例如:t1->then(t2)
2) hetcompute::task_ptr<ReturnType>能建立控制和一些数据的前置依赖,例如:t2→then(t1), t3→bind_all(t2)。然而, task_ptr的类型不能绑定一些数据,因为参数列表信息不在这。
3) hetcompute::task_ptr<ReturnType(Arg...)>能建立控制和数据依赖(前置或者后置),并且绑定数据到计算结构。例如: t3→then(t1), t3→bind_all(t2)。
Note: hetcompute::task_ptr<ReturnType>是一个hetcompute::task_ptr<>。
Note: hetcompute::task_ptr<ReturnType(Args...)>是一个hetcompute::task_ptr<ReturnType>。
4) HetCompute数值任务是一个已启动的任务,它没有计算结构,只有返回值。对于任务代数是很有用的。
5) 第二个创建组模板,任务返回指向该任务的指针,并以相同的方法启动该任务。他是一个hetcompute::create_task(..)和 hetcompute::task::launch(..)的集合。如果任务计算架构用组的模式,那么任务参数必须被绑定。
6) 第三个创建组模板,创建一个任务并且到组中执行。尽可能使用HetCompute快速创建组任务 hetcompute::group::launch(…)
Note: 组模板一的模板模式,使任务创建和任务启动分离成为可能,所以任务一来可以被设置在两个阶段。
Note: 当不需要创建前置任务的情况下,推荐使用组模板二。他比分离的创建和启动更具性能
Note: 组模板三的模板模式,常常用于创建没有依赖需求的线程。这是创建和启动任务最有效的办法。
三、HetComputeSDK任务实例
1、使用Lambda表达式创建任务
a、使用Lambda表达式创建一个t1任务,打印“Hello World”
auto t1 = hetcompute::create_task([] { HETCOMPUTE_ILOG("Hello World!\n"); });
t1→launch();
t1->wait_for();
b、hetcompute::launch(...)或者hetcompute::group::launch(...)创建任务
auto t = hetcompute::launch([] { HETCOMPUTE_ILOG("Hello World!\n"); });
t→wait_for();
auto g = hetcompute::create_group();
g->launch([] { HETCOMPUTE_ILOG("Hello World!\n"); });
g->wait_for();
2、使用Classes创建任务
a、使用定制的class <typename Code>重载class的operator()。
b、也能够通过user_class创建一个目标,然后用目标撞见一个任务
c、使用函数指针创建一个任务