2017-05-03 73 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

我们当然可以想象一个堆栈分配的对象,它有一些用户调用的托管字符(即在实例化之后,或者甚至在构造函数期间,当然会调用它),但这似乎有点扭曲。然而,对象*本身*不会被管理,所以仍然不适用于你的情况。另外,如果我们不是通过引用传递对象,而是通过值来代替,那么您的堆栈案例可能会工作。但是,这些细微差别似乎并不是你问题的焦点。 –

相关问题