我正在阅读本文,该文章解释了统一的内存并浏览了所提供的代码,但我找不到的唯一一件事是,如果能够使用统一的内存,我应该始终分配通过 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
}
堆栈分配:
Object o;
不调用新的。因此,对于CUDA而言,它是一个非托管的对象/分配(因为您的new
运算符必须要求托管内存子系统输入图片(。对于非托管数据,作为内核参数传递:
__global__ void aKernel(Object& obj)
^
是非法的。
,如果您使用cuda-memcheck
运行,您的代码将无法正确运行。您还可以通过在Managed
new
覆盖中列出cout
语句来验证这些断言,并研究其实际和何时打印某物的位置。
通常,AFAIK,托管堆栈分配将需要所谓的Linux HMM补丁,这尚不可用。
还请注意,您显示的代码中有一些句法错误,例如我相信:
p.foo();
应该是:
p->foo();
我相信:
class Object : Managed
应该是:
class Object : public Managed
,但这似乎并不是您问题的重点(如何使该代码工作(。我假设您在问题中显示的Managed
的继承确实是从此处定义的Managed
类继承