Hetcompute sdk中的task介绍

大家好,今天小白给大家简单分享下Hetcompute sdk中task相关的基础知识,欢迎一起交流学习。

一、什么是task

Task 是异步执行的基础单位。具体来说,任务是一个独立的工作单元,它可以在 CPU、GPU、DSP 上异步执行。
任务将计算和数据绑定,包含控制和数据两部分。控制部分可以是一个 C++ 函数,一个(前述) Kernel,或一个模式等;
数据部分则可以是缓冲区、函数参数等。

二、如何创建以及启动task

1、使用Lambda表达式创建任务

Lambda表达式是C ++ 11中的一个新功能,也是创建hetcompute任务的首选参数类型,能够从封闭的范围中捕获变量。

以下代码使用lambda表达式创建一个打印“Hello World!”的任务t1。

#include <hetcompute/hetcompute.hh>

int main()
{

  hetcompute::runtime::init();

  // Create a task that prints Hello World!
  auto t1 = hetcompute::create_task([] { HETCOMPUTE_ILOG("Hello World!\n"); });

  // Launch the task.
  t1->launch();
  // Wait for the task to finish.
  t1->wait_for();
  hetcompute::runtime::shutdown();
  return 0; 

或者,可以使用hetcompute::launch(...) or hetcompute::group::launch(...).

上面的示例中没有捕获变量,假设您想要使用name捕获字符串以进行正确的访问:

#include <hetcompute/hetcompute.hh>

int main()
{

   hetcompute::runtime::init();

   auto g = hetcompute::create_group();  

   std::string name = "HETCOMPUTE";

   // Launching a task in the group.  

   g->launch([name] { HETCOMPUTE_ILOG("Hello World, %s!\n", name.c_str()); });  

   // Wait for g to finish.

   g->wait_for();

   hetcompute::runtime::shutdown();
   return 0; 

2、使用类创建任务

您可以通过重载类的operator()来将任何自定义类用作<typename Code>。 以下代码显示如何从类实例创建任务。 当HetCompute调度程序执行时任务,调用operator()方法。

#include <hetcompute/hetcompute.hh>

class user_class

{

   public:

   explicit user_class(int value) : x(value) {}

   void operator()(int y) { HETCOMPUTE_ILOG("x = %d, y = %d\n", x, y); }

   void set_x(int value) { x = value; }

   private:

   int x;

}

int main()
{

   hetcompute::runtime::init();

   auto g = hetcompute::create_group();    

   g->launch(user_class(42), 27);              // a行

   // Wait for the group to finish.

   g->wait_for();     

   hetcompute::runtime::shutdown();

   return 0;

}

也可以将a行替换为:user_class obj(42); auto t = hetcompute::create_task(obj); g->launch(t, 27);

3、使用函数指针创建任务

最后一种创建任务的方法是通过函数指针;

#include <hetcompute/hetcompute.hh>

void foo();

void foo()

{

  HETCOMPUTE_ILOG("Hello World!\n");

}

int main()
{

   hetcompute::runtime::init();

   // Create a task that executes foo().

   //auto t = hetcompute::create_task(foo); 由于Visual Studio C ++编译器的限制,这在Visual Studio上不起作用。 你可以使用         // lambda函数绕过它.     

   auto t = hetcompute::create_task([] { foo(); });

   // Launch and wait for the task.   

   t->launch();  

   t->wait_for();

   hetcompute::runtime::shutdown();

   return 0;

}

三、task的依赖介绍

HetCompute提供了一种指定任务之间的控制和数据依赖性的方法。 程序员可以统一的方式构建跨越CPU,GPU和DSP的丰富的非循环任务图。 任务可以在任务图中具有多个前驱和后继。 只有在所有(控制和数据相关性)前驱成功完成后,任务才可以执行。

1、Control Dependencies

可以使用hetcompute :: task <> :: then()在任务之间建立控制依赖关系,以指定任务执行的相对顺序。 以下示例显示如何确保任务t1在任务t2之前执行。

 #include <hetcompute/hetcompute.hh>
int main()
{
  hetcompute::runtime::init();
  auto t1 = hetcompute::create_task([] { HETCOMPUTE_ILOG("Hello "); });
  auto t2 = hetcompute::create_task([] { HETCOMPUTE_ILOG("World!"); });
  // Ensure that t1 executes before t2
  t1->then(t2);
  t1->launch();
  t2->launch();
  t2->wait_for();
  hetcompute::runtime::shutdown();
  return 0;
}

在上面的示例中,语句t1-> then(t2)保证t1在t2开始执行之前结束。 因此,只需等待t2完成以确保t1和t2都完成即可。

2、Data Dependencies

任务t2可以依赖于另一个任务t1的数据,如下例所示:

#include <hetcompute/hetcompute.hh>
 int  main()
{
  hetcompute::runtime::init();
  auto t1 = hetcompute::create_task([] { return 42; });
  auto t2 = hetcompute::create_task([](int i) { HETCOMPUTE_ILOG("The answer to life the universe and everything = %d", i); });
  // Set up data dependency from t1 to t2
  t2->bind_all(t1);
  t1->launch();
  t2->launch();
  t2->wait_for();
  hetcompute::runtime::shutdown();
  return 0;

 }

四、task的生命周期

 

                                一个任务通过使用hetcompute::create_task(Code&&), hetcompute::launch(Code&&), etc来创建,至少有一个hetcompute::task_ptr<>指针存在于用户代码中,它可以用来对任务执行操作,绿线状态切换如下描述:

1、在建立控制依赖或者数据依赖之后,使用hetcompute::task<>::launch()来注册任务到HetCompute运行时系统,并且不会向已启动的任务添加其他依赖项。

2、在任务控制或数据相关的所有任务都已转换为“已完成”后,任务将变为Ready状态。

3、当执行资源(CPU,GPU或DSP)变得可用且任务可能使用的任何其他资源(如hetcompute :: buffers)变为可用时,任务将转换为Running状态。

4、最后在任务成功执行之后,任务转换为Completed状态。

红线状态切换如下:

5、如果通过hetcompute :: task <> :: cancel()取消了控制或数据相关的任务或任何任务,则任务将转换为“已取消”状态。(同理6、7、8)

9、某些创建的任务可能永远不会启动,当最后一次hetcompute :: task_ptr <>指向这样的任务超出范围,任务自动取消。任何后续任务也会被取消。

五、总结

本篇主要简单介绍了hetcompute sdk中创建task的三种方法、任务之间的依赖(包括控制依赖和数据依赖)以及任务的生命周期,欢迎一起交流学习。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值