1.記憶體要用 new ::brook::Stream 去產生 CAL 對應裝置 (不一定是 CPU or GPU) 裡的記憶體空間, 如宣告一個 vector, 一維陣列, 內容物是 float, 要 x 個大小:
unsigned int dim[1] = { x };
::brook::Stream<float> = new ::brook::Stream<float>(1, dim);
如果是二維, 假設是 x * y 大小的話:
unsigned int dim[2] = { x, y };
::brook::Stream<float> = new ::brook::Stream<float>(2, dim);
new 後面接的 1 跟 2 就是 dim 指標的最大深度, 也就是需要幾維, 後面會講到的 domain 也會用到這個概念.
##如果陣列內元素是 float4 或 int4 的話, 它一個元素就是 128bit 寬大小而非 32bit. 雖然這算常識但還是要提一下.
##我不確定最大可以到幾維, 好像是 4.
2."<>" 標記, 指的是一個值, 但是這個值是一個 vector 裡的一個元素, 而是哪一個則看它所屬的thread 是第幾個.
3.kernel function 內可以使用 instance() 取得現在是上述 vector 裡的第幾個元素, 如果是一維的話可以使用
int x=instance().x;
取得座標點, 二維可以使用:
int2 p = instance().xy;
int x = p.x; //取出 x 座標的範例.
int y = p.y; //取出 y 座標的範例.
因為 int 裡最大的就是 int4, 內值分別為 int4.x, int4.y, int4.z, int4.w 四個, 所以我猜記憶體最大可用維度應該是四維....
4.盡可能使用 <> 去跑, brook+ 裡會拆成好幾個 thread 去跑 (未證實. 據說這就是 scatter 機能..) 例如以下的 kernel function code:
kernel void copy(float input<>, out float output<>)
{
output = input;
}
假設 input output 兩個 vector 長度都是 x 的話, 就會拆 x 個 thread 各別去做 data copy 的動作..
5.盡可能使用 <> 另一個理由是因為, array output 在目前的 brook+ 裡只能允許有一個.
6.brook+ 內每個 kernel function 不允許擁有自己的 local memory..
7.kernel function 內索引變數可以活用 int4 來做, 例如:
int4 nIDX = { 0, 0, 0, 0 };
int4 nSTP = { 1, 256, 1, 256 };
fOut = pfSrc[nIDX.x] + pfSrc[nIDX.y] + pfSrc[nIDX.z] + pfSrc[nIDX.w];
nIDX += nSTP;
......
int4 也可以改 float4, brook+ 內允許使用浮點數當索引值..
8.brook+ 內 kernel function 不允許呼叫其它的 kernel function..
9.output <> 的值無法拿來給 kernel function 程式做讀取之用, 要讀取再寫入 (a+=b 的場合) 的話要用 reduce 的寫法:
reduce void reduceGPU(float input<>, reduce float output<>)
{
output += input;
}
但是 reduce 的限制很多, 只能有兩個參數, 就是這一進一出..
output [] 這種 array 型態的話就可以, 只是當你程式要讀取時, 通常該被更新的值都沒被更新.
10.kernel function 不可以做指標型態轉換, 也不支援 int <=> float 值的轉換.
11.外面要呼叫像第四個那種 copy function, 但只需要 copy 某一個範圍時, 可以下 domain 參數, 例如:
::brook::Stream<float> a[10];
::brook::Stream<float> b[10];
copy(a.domain(2, 6), b.domain(2, 6));
這樣就可以 copy a[2] ~ a[5] 給 b[2] ~ b[5].
附帶說明一點, 在這種寫法下, kernel function 內 instance().x 抓到的起始值是 0, 不會是 2.
brook+ 一來它是 data parallel 而不像 nvcc 是 thread parallel 導向的做法, 而因為不管計算 float32 x1 或 float32 x4 (float4) ATi GPU 內部都是以 float32 x 4 在演算, 所以使用 float4 會比只用 float 有效率, 所以在這前提之下, 能夠把資料的平行化處理拆散到多少, 會關係效能以外, 甚至影響計算結果是否正確.
真是難寫死了... 特別是資料平行的演算法 -_-
沒有留言:
張貼留言