首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >CUDA:在C++中包装设备内存分配

CUDA:在C++中包装设备内存分配
EN

Stack Overflow用户
提问于 2008-11-18 18:59:22
回答 4查看 9.2K关注 0票数 17

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

我的计划是自己做这件事,使用重载的operator new和placement new和RAII (两个替代方案)。我想知道是否有什么我到目前为止还没有注意到的警告。代码似乎可以工作,但我仍然对潜在的内存泄漏感到疑惑。

RAII代码的用法如下:

代码语言:javascript
复制
CudaArray<float> device_data(SIZE);
// Use `device_data` as if it were a raw pointer.

也许在这种情况下,一个类有点过分了(特别是因为您仍然必须使用cudaMemcpy,这个类只封装RAII),所以另一种方法是placement RAII

代码语言:javascript
复制
float* device_data = new (cudaDevice) float[SIZE];
// Use `device_data` …
operator delete [](device_data, cudaDevice);

在这里,cudaDevice只是作为一个标签来触发重载。然而,由于在普通的位置new中,这将指示位置,我发现语法奇怪地一致,甚至可能比使用类更可取。

我会感激每一种批评。也许有人知道下一个版本的CUDA是否计划在这个方向上做些什么(据我所知,这将改善它对C++的支持,不管他们是什么意思)。

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

  1. 我的placement new重载在语义上是正确的吗?它会泄漏内存吗?
  2. 有没有人有关于未来CUDA开发的信息,这些信息会朝着这个方向发展(让我们面对它: C++ s*ck中的C接口)?
  3. 我如何以一致的方式进一步发展这一点(还有其他API需要考虑,例如,不仅有设备内存,而且还有常量内存存储和纹理内存)?

代码语言:javascript
复制
// 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 <typename T>
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&);
};

关于这里雇佣的单例:是的,我知道它的缺点。然而,这些在这个上下文中是不相关的。这里我所需要的是一个小的类型标签,它是不可复制的。其他的一切(比如多线程的考虑,初始化的时间)都不适用。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2008-11-19 01:26:17

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

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

票数 5
EN

Stack Overflow用户

发布于 2010-07-22 14:51:48

与此同时,还有一些进一步的发展(不是在CUDA API方面,但至少在尝试使用类似STL的方法进行CUDA数据管理的项目方面)。

最值得注意的是,NVIDIA research有一个项目:thrust

票数 7
EN

Stack Overflow用户

发布于 2008-11-19 17:55:57

有几个项目尝试了类似的东西,例如CUDPP

然而,与此同时,我已经实现了自己的分配器,它工作得很好,而且很简单(> 95%的样板代码)。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/299761

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档