我正在阅读解释统一内存的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
}
答案 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