天天看點

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 sdk中的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的三種方法、任務之間的依賴(包括控制依賴和資料依賴)以及任務的生命周期,歡迎一起交流學習。

繼續閱讀