【问题标题】:Does CUDA's unified memory work only for variables in the heap?CUDA的统一内存是否只对堆中的变量有效?
【发布时间】:2017-05-03 13:30:20
【问题描述】:

我正在阅读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
}

【问题讨论】:

  • 回答需要看到一些真实的代码。您的 Objectinheriting 是否与文章中的 Managed 相同?

标签: cuda


【解决方案1】:

堆栈分配:

Object o;

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

__global__ void aKernel(Object& obj)
                              ^

是非法的。

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

一般来说,AFAIK,托管堆栈分配将需要所谓的linux HMM patch,目前尚不可用。

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

p.foo();  

应该是:

p->foo();  

我相信:

class Object : Managed

应该是:

class Object : public Managed

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

【讨论】:

  • 关于 HMM 的好消息不知道。实际上,我重载的唯一运算符是 new 是一个很好的观点,因此它只会触发堆分配对象的 cuda 内存管理。感谢您指出错误。
  • 我们当然可以想象一个堆栈分配的对象,它有一些用户调用的托管字符(即在实例化之后,或者甚至可能在构造函数期间,确实得到当然称为),但这似乎有些扭曲。但是,对象 itself 不会被管理,因此在您的情况下仍然无法工作。此外,如果我们只是不通过引用传递对象,而是通过值传递,您的堆栈案例可能会起作用。但同样,这些细微差别似乎不是您问题的重点。
猜你喜欢
  • 2020-10-29
  • 1970-01-01
  • 2020-06-03
  • 2014-02-17
  • 1970-01-01
  • 2018-05-16
  • 2013-04-06
  • 2020-06-01
  • 2016-12-18
相关资源
最近更新 更多