CUDA知识普及
IT168 CUDA專題: http://www.it168.com/tag/3263_1.shtml
CUDA 深入淺出: http://www.opengpu.org/forum.php?mod=viewthread&tid=2109??? 很詳細的解釋!
異構技術構建云計算平臺:http://tech.it168.com/a2011/1215/1289/000001289157.shtml
Vs13添加CUDA支持 :http://blog.csdn.net/wishchin/article/details/51883142
GPU優化與實例分析:http://tech.it168.com/a2011/1215/1289/000001289225.shtml
(一):兼容庫
thrust快速入門教程:算法:http://tech.it168.com/a2011/0714/1218/000001218181.shtml
????? Thrust是一個類似于STL的針對CUDA的C++模板庫,能夠使程序更簡潔易讀。Thrust提供與CUDA C完全兼容的接口,可以使我們高效地編寫高性能并行程序。通過利用Thrust,程序員得以快速構建CUDA程序,并能夠獲得極高的穩定性和性能與精度,并行排序等例程的速度可提升5至100倍。
Thrust提供了大量的常用并行算法。這些算法與STL的算法非常相似,于是我們使用了相同的名稱(例如thrust::sort 與std::sort)。
所有的Thrust算法可以在主機端和設備端上使用。尤其是,當Thrust算法轉入主機端迭代器時,將會調度主機端路徑,同樣,當使用設備端迭代器時將使用設備端實現。
thrust::copy是一個例外,他可以任意的拷貝主機端和設備端的數據。但是所有的迭代器參數必須符合Thrust算法的要求,要么都在主機端,要么都在設備端。當不能滿足要求的時候,編譯器會報錯。
Transformations
Transformations算法作用是用來將目標容器賦上特定值(例如零)或者特定數列。之前的例子我們已經使用過thrust::fill,可以向所有元素賦特定值。此外transformations算法還包括thrust::sequence、thrust::replace、thrust::transform。完整的列表請參考文檔。
下面的代碼演示了幾個transformation算法的用法。注意類似于C++中擁有的thrust::negate和thrust::modulus,Thrust在thrust/functional.h中也提供了,此外還有plus與multiplies等。
# include <thrust/ device_vector .h># include <thrust/ transform .h>
# include <thrust/ sequence .h>
# include <thrust/ copy .h>
# include <thrust/ fill .h>
# include <thrust/ replace .h>
# include <thrust/ functional .h>
# include <iostream>
int main ( void )
{
// allocate three device_vectors with 10 elements
thrust :: device_vector <int> X (10) ;
thrust :: device_vector <int> Y (10) ;
thrust :: device_vector <int> Z (10) ;
// initialize X to 0,1,2,3, ....
thrust :: sequence (X. begin () , X. end ());
// compute Y = -X
thrust :: transform (X. begin () , X.end () , Y. begin () , thrust :: negate<int>() );
// fill Z with twos
thrust :: fill (Z. begin () , Z. end () , 2);
// compute Y = X mod 2
thrust :: transform (X. begin () , X.end () , Z. begin () , Y. begin () , thrust :: modulus<int-
>() );
// replace all the ones in Y with tens
thrust :: replace (Y. begin () , Y. end () , 1, 10) ;
// print Y
thrust :: copy (Y. begin () , Y. end () , std :: ostream_iterator<int>( std :: cout ,"\n"));
return 0;
}
thrust/fuctuional.h中的函數提供了大部分內置代數和比較運算,但是我們想提供更多出色的功能。比如,運算y < - a * x + y,x、y為向量,a為常數標量。這其實就是我們所熟知的由BLAS提供的SAXPY運算。
如果我們在thrust中實現SAXPY我們有幾個選擇。一個是,我們需要使用兩個transformations(一個加和一個乘法)還有一個臨時數則用于存儲a乘后的值。另一更佳選擇是使用一個單獨的由用戶自己定義函數的transformation,這才是我們真正先要的。我下面用源代碼解釋說明這兩種方法。
struct saxpy_functor{
const float a;
saxpy_functor ( float _a) : a(_a) {}
__host__ __device__
float operator ()( const float& x,constfloat& y)const {
return a * x + y;
}
};
void saxpy_fast (float A, thrust :: device_vector<float>& X, thrust :: device_vector<-
float >& Y)
{
// Y <- A * X + Y
thrust :: transform (X. begin () , X.end () , Y. begin () , Y. begin () , saxpy_functor (A));
}
void saxpy_slow (float A, thrust :: device_vector<float>& X, thrust :: device_vector<-
float >& Y)
{
thrust :: device_vector <float> temp (X. size ());
// temp <- A
thrust :: fill ( temp . begin () , temp . end () , A);
// temp <- A * X
thrust :: transform (X. begin () , X.end () , temp . begin () , temp . begin () , thrust ::-
multiplies <float>() );
// Y <- A * X + Y
thrust :: transform ( temp . begin () , temp . end () , Y. begin () , Y. begin () , thrust :: plus<-
float >() );
}
Saxpy_fast和saxpy_slow都是有效的SAXPY實現,盡管saxpy_fast會比saxpy_slow更快。忽略臨時向量分配與代數運算的花費,其開銷如下:
fast_saxpy:2N次讀取和N次寫入
slow_saxpy:4N次讀取和3N寫入
因為SAXPY受到內存約束(它的性能受限于內存的帶寬,而不是浮點性能)更大量的讀寫操作使得saxpy_slow開銷更加昂貴。而saxpy_fast執行速度與優化的BLAS實現中的SAXPY一樣快。在類似SAXPY內存約束算法通常值得使用kernel融合(合并多個計算于單獨的kernel)的方法以最小化內存的讀寫交換。
(二):基于gpu的異構程序開發流程:
http://www.cnblogs.com/viviman/archive/2012/11/23/2784424.html
異構程序開發的特點決定了開發與傳統開發手段還是有一些列不同的,通俗的說有一定的講究。針對本項目,本章列出幾條重要的值得注意的地方,從開發過程上指導整個流程,以保證程序的質量+和優化。對異構程序的開發,針對自己的開發業務,簡單的敘述整個開發流程如圖:
這個過程文字敘述為:
過程1:數據準備
準備需要處理的業務的原始數據,比如你的數據來源為mysql或者app或者mongodb或者其他的,通常為了測試,我都會寫一個生產隨即浮點數的函數來模擬自己的項目。
過程2:業務邏輯設計
更加業務需求的功能,設計業務層的類,投資組合類大體上有4個功能,每個功能直接又是有依賴關系的,這個過程產生的軟件產品是——類圖。
過程3:業務邏輯實現
指的是在CPU中實現,可以被其他APP調用的接口;我建議將可并行和非可并行的事物邏輯都封裝在這個業務類中,如果有并行的處理模塊,在下一個軟件過程中處理。這個過程產生的軟件產品是——類的.h和.cpp。我時刻提醒自己——不急于求成并行模塊的內核程序書寫。
過程4:數據詞典設計
為什么把這個過程放在這個地方,其實是不對的,因為數據從數據庫中出來,到最后計算出來的數據存入數據庫,這個整個過程都涉及到的東西,不應該放到這個地方。就像圖中表示的一樣,數據詞典貫穿始終。
但是,放在這個過程中是有一定意義的,因為一個數據塊放到一個gpu中進行并行計算,并且要從設備中拷貝出來,一個好的數據類型,對設備與主機傳遞的帶寬和設備內存的使用都是具有重要意義的。很簡單的說,誰都不愿意把一群沒計算意義的string類型的字符串拷貝到gpu中,只作為標示一個計算結果的id來用,對吧。所以,數據詞典設計也是一個迭代的過程,開發過程中發現數據詞典可以優化,盡量優化!
數據詞典的設計,原則是以設備gpu為服務對象,青睞設備原則。
何謂輕重之分,數據詞典的設計,在異構開發中顯得很重要。我們不求一步到位,但求改進。
過程5:內核程序設計
內核程序就是在gpu上開發的并行計算程序。
過程3中如果某個功能模塊發現并行粒度很大,那么,我們要開始做真正有意義的事情了。
為了強調程序架構的清晰——
我們先建立.cuh文件,聲明要并行計算的功能模塊,注意,我們過程3中的業務功能只需要包含這個.cuh文件,就可以調用封裝好的并行計算模塊啦。
接著我們建立.cu文件,注意,所有內核操作的符號,必須在cu文件中實現。我們在cu文件中實現內核函數,處理并行的數據。
是的,內核程序我們不要嫌多寫個頭文件,多一個頭文件,對于程序的架構是很有幫助的,工程化!
過程6:迭代優化
這里有兩個意義上的優化:
第一,我們始終不能忘記業務上是否還可以進一步的優化;
第二,我們最期待的內核程序算法上的優化。
也許第二個是我們會更加有挑戰,很簡單的例子,我的排序算法就是比你的排序算法高級、快速;或者我的程序就是比你的程序使用的內存少、指令吐量大。我們在開發內核程序時,盡量不要浪費內核的資源,更杜絕可能的情況下內存越界和顯露,這個后果不是軟件崩潰,而是系統藍屏!
最后一條,圖中沒有加,就是每一個版本,我們都保存記錄,分析效率,作為自己優化程序的階段性產品。我試圖從cpu到gpu的每個版本都進行了版本定稿,這樣,整個過程將是有趣的,我看到每個版本都在提升,會很得意。是的,原來——
我提醒自己注意,異構程序,步步為營,一步一個版本,逐個比較,穩定提高效率和質量!
總結
- 上一篇: 家用万兆高性价比路由器选择-家用万兆高性
- 下一篇: 飞畅科技—电信级E1保护倒换设备产品介绍