如何在cuda上创建全局可访问的变量?

时间:2012-10-08 13:50:44

标签: c++ cuda memory-pool

这是一个非常复杂的问题,我不是母语为英语的人,所以如果你有足够的耐心来阅读我的问题,我会感谢你。

由于Cuda实际上是在两台计算机上运行,​​当你在设备上时指向主机的内存是无效的,这意味着如果它们有指针成员你就不能将结构(或对象)复制到设备。

我尝试使用以下系统来解决此问题:

  1. 使用整数而不是指针。整数是内存池中的偏移量。整数包含在一个类中(重载“ - >”和“*”),使其看起来像一个指针。
  2. 内存池对象管理连续的对象数组,可以轻松地将其传输到Cuda设备。池的内容在主机和设备之间同步,因此整数偏移在两个方面都具有相同的含义。
  3. 为方便使用偏移量,应将其包裹起来。在主机端,包装器看起来像这样:

    template<typename T>
    class MemPoolPointer {
    public:
        inline T* operator -> () const
        {
            return &( MemPool<T>::get_instance.get_object(_p) );
        }
        uint64_t _p;
    }
    

    我们可以看到,指针类需要全局访问内存池。这通常通过使内存池为单例来实现。但是,Cuda不允许静态成员,并且它将__device__变量限制为文件范围。我该如何解决这些限制?或者我应该尝试OpenCL?

1 个答案:

答案 0 :(得分:1)

OP能够通过使用如下的静态类方法包装全局范围__device__变量来解决这个问题:

class FooBar;
__device__ FooBar* FOOBAR_DEVICE_POOL;
class FooBar
{
    __device__ static FooBar& DEVICE_GET(uint64_t p);
}

template<typename T>
class MemPoolPointer {
public:
    inline T* operator -> () const
    {
#ifdef __CUDA_ARCH__
        return &( T::DEVICE_GET(_p) );
#else
        return &( MemPool<T>::get_instance.get_object(_p) );
#endif
    }
    uint64_t _p;
}

[此答案作为社区wiki条目添加,以便从CUDA标记的未答复队列中获取问题]