CUDA Unified Memory / C ++ - 成员函数访问冲突

时间:2014-12-16 22:17:04

标签: c++ visual-studio-2013 cuda

我遇到了CUDA 6.0统一内存的问题;对于某些对象,可以从CUDA内核访问成员变量,但成员函数不是(并且尝试使用它们会导致内存访问冲突)。我基本上将C ++项目移植到CUDA并使用命名空间来保存实际的CUDA内核。

有一个名为“Managed”的类,它是需要在CPU和GPU内存空间之间移动的所有类的父类。该类替换了CUDA 6.0 parallel forall blog post中描述的new和delete运算符。它看起来像这样:

#include "Managed.h"

//  Overrides new operator
//  Used to have "new" create Unified CUDA Host/Device pointers
//  This makes memory management a lot easier
__host__ __device__ void* Managed::operator new(size_t len)
{
    void *ptr;
    cudaMallocManaged(&ptr, len);
    return ptr;
}// end operator new

//  Overrides delete operator
__host__ __device__ void Managed::operator delete(void* ptr)
{
    cudaFree(ptr);
}

__host__ __device__ Managed::Managed()
{
}


__host__ __device__ Managed::~Managed()
{
}

有一个类World,其中包含一些成员变量和函数。此类的实例在CPU上进行了修改并在GPU上使用,因此它扩展了Managed。标题World.h的一部分如下所示:

class World:
    public Managed,
    public IntersectableContainer
{
public:
    __host__ __device__ World();
    __host__ __device__ ~World();
    int light_count;//<-This was private, but I moved it to public temporarily
    __host__ __device__ int getLightCount() const;
[...]
private:
[...]

成员函数getLightCount()如下所示:

//  Return number of lights in scene
__host__ __device__ int World::getLightCount() const
{
    return light_count;
}

最后,CUDA内核位于名为GPGPUCam的命名空间中。内核从类Window启动,该类具有指向CameraWorld的指针。内核能够访问World成员变量,但无法使用任何成员函数。这是内核:

//  Cuda rendering kernel
__global__ void GPGPUCam::CUDARenderScene(World* const world, Camera* const camera, uchar4* target, int width)
{
    int x = (blockIdx.x * blockDim.x) + threadIdx.x;
    int y = (blockIdx.y * blockDim.y) + threadIdx.y;
    int lc = world->light_count;//<-Works fine (tested in debugger)
    lc = world->getLightCount();//<-Memory access violation happens here
}

这是CUDA内存检查器的输出。我运行1个块和1个线程/块来减少输出的长度,这就是为什么只有1个访问冲突。

Summary of access violations:
[...]\gpgpucam.cu(31):error MemoryChecker: #misaligned=0  #invalidAddress=1
================================================================================

Memory Checker detected 1 access violations.
error = access violation on load (global memory)
gridid = 8
blockIdx = {0,0,0}
threadIdx = {0,0,0}
address = 0x13ff44ef0
accessSize = 8

奇怪的是,Camera也扩展了Managed,我可以从同一个内核访问其成员函数。

每个源文件以.h(标题)或.cu(C ++ / CUDA文件)结尾,每个.cu文件在Visual Studio属性页中设置为CUDA C / C ++文件,因此使用{{ 1}}。

NVCC 6.5.13版,Visual Studio 2013

我希望在没有粘贴整个项目的情况下,我已经提供了足够的信息。谢谢你的帮助!

0 个答案:

没有答案