Hello C++ AMP!


導讀:C++ AMP是微軟提供的一套利用GPU並行計算的API. GPU運算不是新概念,用GPU運算比較有名的已有NVIDIA的CUDA,AMD的stream. 同時對於OpenCL這個標准大家也一定沒見過也聽說(AMP同樣與近日放出了開放標准).但是至少目前比較成氣候的CUDA,他只能用在N卡上,歸根結底是由於CUDA用到N家的驅動,所以A卡不能用。那么OpenCL呢?很多大廠也都有自己獨特的變種,所以還不能說真正的一次編譯,全平台運行。而AMP就利用到了得天獨厚的平台優勢,假如你用windows,用AMP是不二之選。當然有個前提,天下沒有免費的午餐,您的顯卡要支持DX11才行。

說了這么多,讓我們看看AMP什么樣子吧,下面是段類似於Hello world的AMP 代碼片段:

 1 #include <iostream>
2 #include <amp.h>
3
4 void MatrixMultiplySimple(std::vector<float>& vC,
5 const std::vector<float>& vA,
6 const std::vector<float>& vB, int M, int N, int W)
7 {
8 concurrency::array_view<const float,2> a(M, W, vA);
9 concurrency::array_view<const float,2> b(W, N, vB);
10 concurrency::array_view<float,2> c(M, N, vC); c.discard_data();
11 concurrency::parallel_for_each(c.extent,
12 [=](concurrency::index<2> idx) restrict(amp) {
13 int row = idx[0]; int col = idx[1];
14 float sum = 0.0f;
15 for(int i = 0; i < W; i++)
16 sum += a(row, i) * b(i, col);
17 c[idx] = sum;
18 });
19 }
20
21 int main()
22 {
23 std::vector<float> vec_rslt(9);
24 std::vector<float> vec_A;
25 std::vector<float> vec_B;
26
27 vec_A.push_back(1.0f);vec_A.push_back(0.0f);vec_A.push_back(0.0f);
28 vec_A.push_back(0.0f);vec_A.push_back(1.0f);vec_A.push_back(0.0f);
29 vec_A.push_back(0.0f);vec_A.push_back(0.0f);vec_A.push_back(1.0f);
30
31 vec_B.push_back(11f);vec_B.push_back(21f);vec_B.push_back(31f);
32 vec_B.push_back(12f);vec_B.push_back(22f);vec_B.push_back(32f);
33 vec_B.push_back(13f);vec_B.push_back(23f);vec_B.push_back(33f);
34
35 MatrixMultiplySimple(vec_rslt, vec_A, vec_B, 3,3,3);
36
37 std::cout<<vec_rslt[0]<<"|"<<vec_rslt[1]<<"|"<<vec_rslt[2]<<std::endl;
38 std::cout<<vec_rslt[3]<<"|"<<vec_rslt[4]<<"|"<<vec_rslt[5]<<std::endl;
39 std::cout<<vec_rslt[6]<<"|"<<vec_rslt[7]<<"|"<<vec_rslt[8]<<std::endl;
40
41 return 0;
42 }


如果你已經裝上了vs11的beta,那么ctrl+c/ctrl+v趕緊體驗下吧:)

好吧,在這個c++十分激進的年代(近期的c++11和這個AMP,喜歡研究的童鞋又可以虐待自己的腦細胞了),上面代碼肯定讓你有不少迷糊的地方,下面我根據個人經驗跟大家分析下,分析的不好,不要扔鞋哦。。。

首先看line2,用api,一定要包含頭文件,我們的AMP十分為大家着想,只需要這么簡單一個頭文件就行了。用過DX的童鞋一定還記得那include無盡的dxxxx.h和dxxxx.lib.

接着line4 -> line19是比較核心的地方, 這個是我們這個矩陣運算的精髓.8,9,10三個類型定義,我們暫且不管,接着往下看,一個

parallel_for_each
他其實是個函數,我第一眼還以為是個類似於關鍵字for的東東.
他有兩個參數,第一個是種成為extent的東西,目前為了便於理解,你可以理解為一個數組的維度.第二個參數是一個lambda.這里大家都玩.NET的,對lambda一定不陌生,概念上不需要多講,主要一點如果對c++lambda陌生,可以參考這里.
我們看看這個lambda里面都做了些什么?
[=]表示lambda里捕捉的變量按照傳值來引用,
restrict(amp)表示這段代碼運行在默認Device上.你還可以指定是cpu.(ps.在AMP 1st Release中, 有direct3d.)
concurrency::index<2> idx 這個lambda的參數表示的是個線程單位,當前我們可以認為lambda傳幾個idx,就有幾個線程.
至於lambda里面的函數,就是利用數據並行做的計算,簡單的矩陣相乘.
好吧,說到這里止不住,如果你有興趣繼續看下去,我再分享下AMP的一些基本概念:
通過上面代碼分析,你一定比較AMP的基本運作機制.說到這里,有三個屬於必須拋出來:index,extent,gird.
grid,按照字面理解,就是一個網格.我們可以把一個6x6的網格理解為一個grid.三維的話就類似於魔方了.

圖中棕色圖形就是一個index<2>(0,0),extent<2>(5,5)的grid.
藍點就是index,紅框就是兩個小grid,一個是基於index<2>(0,2),extent<2>(2,2)的gird.另一個自己算下吧.
以后有時間,會繼續和大家探討AMP!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM