2011-04-28 34 views
0

嘿, 到目前爲止,我的理解如下:GTX460 1GB(GF104)有2GPC每個4個SM,因此總計8SM其中1被禁用,這意味着:7SM(「流式多處理器」)。每個SM有48個CUDA核心(就是我們所說的線程?可以理解爲CPU的一個核心,例如Q9550-Quadcore?),所以共有336個CUDA核心。Cuda:GTX460的體系結構和代碼相關的網格/塊/線程分離

所以我現在不明白:爲什麼這個'複雜'的架構,不僅像在CPU上說:'好吧,GPU有N個核心,多數民衆贊成它!'?

假設我有一個分爲B塊和每個T線程塊(總共B * T線程)的網格的程序,我可以不知何故告訴一個塊總是連接到一個SM或NOT ?因爲如果這樣的話,這會讓編碼器變得更加困難,因爲他應該知道有多少SM可以優化每張圖形卡的並行。例如:當我有一個帶有8個SM的圖形卡,並且我的程序只將數據分成一個帶有N個線程的1個塊的網格時,我只能使用一個不會使用其所有資源的SM!

有沒有什麼辦法可以在編寫我的程序時只使用卡的某些線程?我真的很喜歡通過在1..M線程上運行我的程序來加速基準測試,其中M是cuda內核的總數(如果這相當於'線程'),但是如何執行此操作?它是足夠的代碼我的程序這樣的:

cudaKernel<<<1, 1>>>(...) 

cudaKernel<<<1, M>>>(...) 

每次運行呢?這是我在這裏看到的唯一的問題是:假設我有簡單的向量加法例子:

#define SIZE 10 
__global__ void vecAdd(float* A, float* B, float* C) 
{ 
    int i = threadIdx.x; 
    A[i]=0; 
    B[i]=i; 
    C[i] = A[i] + B[i]; 
} 
int main() 
{ 
    int N=SIZE; 
    float A[SIZE], B[SIZE], C[SIZE]; 
    // Kernel invocation 

    float *devPtrA; 
    float *devPtrB; 
    float *devPtrC; 
    [...] 
    vecAdd<<<1, N>>>(devPtrA, devPtrB, devPtrC); 
} 

當我現在會設置vecAdd<<<1, N>>>vecAdd<<<1, 1>>>單線程不會計算C到A N-大小的矢量因爲唯一的線程只會計算A,B的第一個值,因此C。如何克服這個問題呢? 非常感謝提前澄清!你會幫助我很多!

回答

2

大部分情況下,你所問的大多數問題的答案是否定的。不只是不,但是沒有。

大多數GPU編程的總體思路是它應該是隱式可擴展的 - 即,您的代碼會自動使用盡可能多的內核。特別是,當它被用於圖形處理時,內核在執行三種着色器(頂點,幾何,片段/像素)之間被分割。因此,可用內核的數量可以(並且通常會)根據總體負載動態變化。

GPU以這種方式組織起來有幾個原因,而不像典型的多核CPU。首先,它主要用於「令人尷尬的並行」問題 - 顯然,它的主要目的是將相似的代碼應用於大量像素中的每一個。儘管在使用CUDA代碼時不會完全相同,但這仍然是硬件設計的基礎。其次,如上所述,核心實際上至少在三個不同的目的之間進行分割,並且可以在更多(例如,使用某些核心的圖形應用程序和使用其他核心的CUDA代碼)之間進行分割。第三,額外的抽象有助於保持你的代碼不受硬件變化的影響。它可以讓你指定你所需要的計算,並且它可以儘可能有效地在硬件上進行調度。

+0

感謝迄今。我是否正確地假設一個線程與cuda核心相同(與四核CPU的四個核心之一相同)? 進一步說明:是否有可能在我的程序中限制線程的數量以及如何在我的示例中執行該操作? – tim 2011-04-29 09:53:31

+0

@ bjoern:不是。一個線程與核心不一樣。線程是CUDA中並行工作的最小虛擬化單元。作爲程序員,您可以顯式控制運行的線程數量,但不能顯示這些線程與物理硬件的關係。 – talonmies 2011-04-29 10:34:56

+0

好吧,我怎麼知道最大。有336個CUDA核心時,在GTX460上線程的數量是多少?每個核心都有固定數量的線程? – tim 2011-04-29 10:53:19