2009年12月4日 星期五

CUDA工作排程的了解


寫了一點CUDA程式,但對於寫出最佳程式並沒有什麼好辦法去了解,難到只有實測一途了嗎?
當然不是,可以找一下CUDA SDK中有一個試算表CUDA_Occupancy_calculator.xls。
玩了試算表,就可以稍為了解CUDA指令排程,其實和發動的執行時所使用資源有關。

可以發現只有三項資源可以調整。
1. 每一個Block使用多少Threads
2. 每一個Thread使用多少Registers
3. 每一個Block使用多少Shared memory

使用CUDA寫程式時對於每一個Block使用多少資源是很明確的,但對於每一個Thraeds使用多少Registers則不是可以直接得到。
不過調整一下數值可以發現CUDA的排程限制。

從文件可以知道一次CUDA指令可以有32個核心動作,這個叫Wraps。在不同核心架構下一次可以發動的Wraps數目不同。
因為工作上是以Block為主要規劃,所以Threads的數目除以32就是Wraps數。
像Bee用的G9600M最大的Wraps數目是24,24是不太好的數字,因為Bee寫的程式動作大部分和2的倍數有關,所以常常無法有效使用。

但不是可以使用的Threads多,Wraps數目就會多,因為因為每一個Threads都是一個core task會用掉Registers。對每一個multiprocessor來說,Registers數目是有限的。
所以就會有Registers總數限制,就是第二項要控制的。

通常一個Block會有共有的變數,此時就要使用到Shared memory,這項資源為每一個multiprocessor才有,所以又變成另一個限制。
由此可以看到一件事,雖然一個multiprocessor有八個core,但可以執行的Threads數目不是八。
可能Threads數目是32,八個core要分成四次執行。
另一種可能是因資源用完,32個Threads是分成4個multiprocessor去做。
若是資源使用很多,有可能每一個multiprocessor只能使用4 core,這時1個wraps會佔用更多的multiprocessor。

可以見得使用比較好的顯卡,因為Multiprocessor多,所以可以解比較耗資源的threads task。
以上為玩試算表所得的心得,實際上可能要實驗才能證實。

玩過後,發現程式工作如果分得比較細小的程式段,會有助於執行分配。
但要分到多細小,真的就要用這個試算表下去估了。

沒有留言:

張貼留言