2017-05-03 76 views
0

我正在閱讀this article,它解釋了統一內存,並且還通過了the code,但我唯一無法找到的是如果爲了能夠使用統一內存,我應該始終通過新的分配對象,得到運行時錯誤。CUDA的統一內存僅適用於堆中的變量嗎?

我是否缺少CUDA的某些配置?我正在使用安裝了CUDA 8.0的GTX 760。

class Object : Managed 
{ 
    Object(){//do something} 
    void foo() {//do something else} 
}; 

__global__ void aKernel(Object& obj) 
{ 
    //do something in parallel with the object 
} 

int main() 
{ 
    Object o; 
    aKernel<<<b,t>>>(o); 
    cudaDeviceSynchronize(); 
    o.foo();     // ERROR 

    Object* p = new Object; 
    aKernel<<<b,t>>>(*p); 
    cudaDeviceSynchronize(); 
    p.foo();     // GOOD 
} 
+0

回答將需要看到一些真實的代碼。你的'Object'是否與文章中的'Managed'類一樣? – talonmies

回答

2

的堆棧分配:

Object o; 

does not invoke new。因此,對於CUDA,它是一個非託管對象/分配(因爲必須調用被覆蓋的new運算符才能讓託管內存子系統輸入圖片)。對於非託管數據,通過引用作爲內核參數:

__global__ void aKernel(Object& obj) 
          ^

是違法的。

而且如果要使用cuda-memcheck運行它,代碼將無法正確運行。您也可以通過將cout聲明放在覆蓋範圍內來驗證這些聲明,並研究它實際打印內容的位置和時間。

一般來說,AFAIK,託管堆棧分配將需要所謂的linux HMM patch,這還不可用。

還要注意,在代碼中的幾個語法錯誤,你所顯示的,例如我相信:

p.foo(); 

應該是:

p->foo(); 

,我相信:

class Object : Managed 

應該可能是:

class Object : public Managed 

但這似乎不是你的問題(如何讓這個代碼工作)的觀點。我已經假設你在你的問題中顯示的Managed的繼承確實繼承自Managed定義的類here

+0

關於HMM的好消息不知道。它實際上是一個很好的觀點,我重載的唯一操作符是** new **,因此它只會觸發對堆分配對象的cuda內存管理。感謝您指出錯誤。 – BRabbit27

+0

我們當然可以想象一個堆棧分配的對象,它有一些用戶調用的託管字符(即在實例化之後,或者甚至在構造函數期間,當然會調用它),但這似乎有點扭曲。然而,對象*本身*不會被管理,所以仍然不適用於你的情況。另外,如果我們不是通過引用傳遞對象,而是通過值來代替,那麼您的堆棧案例可能會工作。但是,這些細微差別似乎並不是你問題的焦點。 –

相關問題