当前位置:  开发笔记 > 编程语言 > 正文

CUDA:用C++包装设备内存分配

如何解决《CUDA:用C++包装设备内存分配》经验,为你挑选了2个好方法。

我现在开始使用CUDA并且不得不承认我对C API有点失望.我理解选择C的原因,但是语言基于C++而不是,有几个方面会更简单,例如设备内存分配(via cudaMalloc).

我的计划是这样做我自己,用重载operator new与安置new和RAII(两种选择).我想知道到目前为止我是否有任何警告.代码似乎工作,但我仍然想知道潜在的内存泄漏.

RAII代码的用法如下:

CudaArray device_data(SIZE);
// Use `device_data` as if it were a raw pointer.

也许一个类在这种情况下是过度的(特别是因为你仍然必须使用cudaMemcpy,该类只封装RAII)所以另一种方法是放置new:

float* device_data = new (cudaDevice) float[SIZE];
// Use `device_data` …
operator delete [](device_data, cudaDevice);

这里,cudaDevice仅作为触发过载的标签.但是,由于在正常放置中new这将指示放置,我发现语法奇怪地一致,甚至可能更喜欢使用类.

我很欣赏各种批评.是否有人知道是否计划为下一版本的CUDA(正如我所听到的那样,将改进其C++支持,无论它们的含义是什么).

所以,我的问题实际上有三个:

    我的展示位置是否new超载语义正确?它会泄漏内存吗?

    有没有人有关于未来CUDA发展的信息,这是朝着这个大方向发展的(让我们面对它:C++ s*ck中的C接口)?

    如何以一致的方式进一步采取这种方式(还有其他需要考虑的API,例如,不仅有设备内存,还有常量内存和纹理内存)?


// Singleton tag for CUDA device memory placement.
struct CudaDevice {
    static CudaDevice const& get() { return instance; }
private:
    static CudaDevice const instance;
    CudaDevice() { }
    CudaDevice(CudaDevice const&);
    CudaDevice& operator =(CudaDevice const&);
} const& cudaDevice = CudaDevice::get();

CudaDevice const CudaDevice::instance;

inline void* operator new [](std::size_t nbytes, CudaDevice const&) {
    void* ret;
    cudaMalloc(&ret, nbytes);
    return ret;
}

inline void operator delete [](void* p, CudaDevice const&) throw() {
    cudaFree(p);
}

template 
class CudaArray {
public:
    explicit
    CudaArray(std::size_t size) : size(size), data(new (cudaDevice) T[size]) { }

    operator T* () { return data; }

    ~CudaArray() {
        operator delete [](data, cudaDevice);
    }

private:
    std::size_t const size;
    T* const data;

    CudaArray(CudaArray const&);
    CudaArray& operator =(CudaArray const&);
};

关于这里使用的单身人士:是的,我知道它的缺点.但是,这些与此无关.我在这里需要的只是一个不可复制的小型标签.其他所有内容(即多线程注意事项,初始化时间)都不适用.



1> kynan..:

与此同时,还有一些进一步的发展(在CUDA API方面并不多,但至少在试图采用类似STL的CUDA数据管理方法的项目方面).

最值得注意的是,有一个来自NVIDIA研究的项目:推力



2> coryan..:

我会选择新的方法.然后我将定义一个符合std :: allocator <>接口的类.理论上,您可以将此类作为模板参数传递给std :: vector <>和std :: map <>等等.

请注意,我听说做这些事情充满了困难,但至少你会以这种方式学习更多关于STL的知识.而且您不需要重新发明容器和算法.

推荐阅读
保佑欣疼你的芯疼
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有