2017-02-08 28 views
0

我是cuda新手,所以我希望我的問題不完全脫離基礎。 我想在全局設備內存上創建一個數組,但我只知道它在我的主要功能中間有多大(但在我訪問設備之前)。從主CUDA聲明設備變量

因爲我不知道大小我無法將代碼之前聲明: 設備 myArr,該[]

所以我想創造主,d_myArr指針,然後使用cudaMalloc d_myArr的( ,arrSize)在設備上分配內存,但我從來沒有真正在設備上聲明變量。

我沒有看到將d_Arr發送到我的內核的原因,因爲它只會存在於該內核中(我認爲?),我只是希望變量作爲全局變量存在於我的設備中,並可以被不同的內核訪問。

我可以在main聲明一個設備變量嗎?如在:

int main(){ 
    . 
    . 
    __device__ myArr[size]; 
    . 
    . 
} 

如果是這樣,它由於某種原因泄露(因爲我找不到任何人這樣做)。如果這是不允許的,我能做些什麼呢?我看到有人提到cudaMemcpyToSymbol,但我無法弄清楚它是否與我想要的完全相同,如果是的話,我會很高興如果有人能夠準確解釋如何使用它來實現我所需要的。

在側面的問題,我也有一個常數變量,我想在我的設備和主機上都存在。現在我只是宣佈了兩次,一次用設備,一次沒有,有沒有更好的方法來做到這一點?

回答

2

這不起作用。

  1. __device__變量必須在全球範圍內聲明。
  2. 在編譯時必須知道與__device__變量關聯的分配大小。

取而代之,只要使用cudaMalloc爲變量分配空間,一旦您知道所需的分配大小。該方法允許動態分配全局變量。 __device__方法只允許靜態分配全局變量。

像這樣:

int main(){ 
    // ... 
    int *d_data; 
    cudaMalloc(&d_data, size*sizeof(int)); 
    // ... 
    kernel1<<<...>>>(d_data,...); 
    // ... 
    kernel2<<<...>>>(d_data,...); 
    // ... 
} 

它是完全合法的這樣的動態分配的全局變量傳遞給一個以上的內核我上面示出,並且將數據或修改通過上述kernel1放在那裏(如果任何)將在上面kernel2中運行的代碼可見,例如我已經展示過。

對於常量變量問題,您提到的方法是合理的。如果您擁有編譯時未知的常量數據,那麼這是一個明智的方法(您也可以使用__constant__而不是__device__進行調查)。如果在另一方面,你有恆定的數據在編譯時已知的,則無論是使用

#define MYCONSTANT 123 

constant int myconstant=123; 

在全局範圍(即main外)將允許這樣的定義可以在主機或設備代碼中同等使用,無需申報或管理兩次。對於POD數據類型(例如int,float,double等),這最後一種方法可以很好地工作,但不適用於像struct這樣的複雜類型。

+0

感謝您的迴應! 就這樣,我可以確保我正確理解,因爲我在設備中分配了內存,它不會丟失,即使我不使用cudaMemcpy來回信息,我的第二個內核中的s_sata將與我的第一個內核的結束,對吧?所以只要我重新發送指向我所有內核的指針,它們都可以引用該變量,否則,如果我不重新發送該變量,它仍然存在於分配的內存中,但我沒有引用來訪問它。 –

+0

是的,一旦你用'cudaMalloc'分配了設備內存,它就是** persistent **,直到你對它調用一個'cudaFree'操作(或者直到你的應用程序終止)爲止。它的行爲與其他任何內存一樣。一旦你寫了一些東西,後續的操作可以看到寫了什麼,不管是後續的內核還是後續的'cudaMemcpy'操作。 –