CUDA的统一内存是否仅适用于堆中的变量?

时间:2017-05-03 13:30:21

标签: cuda

我正在阅读解释统一内存的this article并且还提供了the code,但我唯一看不到的是,为了能够使用统一内存,我应该始终分配对象堆通过 new ,否则我得到运行时错误。

我错过了一些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
}

1 个答案:

答案 0 :(得分:2)

堆栈分配:

Object o;

does not invoke new。因此,对于CUDA,它是一个非托管对象/分配(因为必须调用被覆盖的new运算符以使托管内存子系统进入图片)。对于非托管数据,将引用传递为内核参数:

__global__ void aKernel(Object& obj)
                              ^

是非法的。

如果您使用cuda-memcheck运行代码,则代码将无法正常运行。您还可以通过在cout Managed覆盖中添加new语句来验证这些断言,并研究它实际打印内容的位置和时间。

通常,AFAIK,托管堆栈分配将需要所谓的linux HMM patch,但尚未提供。

另请注意,您所显示的代码中存在一些语法错误,例如我相信:

p.foo();  

应该是:

p->foo();  

我相信:

class Object : Managed

应该是:

class Object : public Managed

但这似乎不是你的问题(如何使这个代码工作)。我假设您在问题中显示的Managed的继承确实继承自Managed类定义的here