如何使用shared_ptr实现CUDA API类型cudaEvent_t的RAII

时间:2018-02-21 11:21:46

标签: cuda shared-ptr raii

CUDA API的类型需要类似于内存分配new和delete的create()和destroy()调用。本着RAII的精神,而不是必须调用cudaEventCreate(& event)和cudaEventDestory(事件),我为cudaEvent_t编写了以下包装器。

我的问题:这个可接受的代码是否没有任何明显的错误?

它为我而建,我还没有发现问题。但我特别不喜欢reinterpret_cast<> trickery用于通过shared_ptr的自定义Allocater和Deleter获取cudaEvent_t变量。

一些相关帖子:

CUDA: Wrapping device memory allocation in C++

Is there a better/cleaner/more elegant way to malloc and free in cuda?

class CudaEvent {
private:
    struct Deleter {
        void operator()(cudaEvent_t * ptr) const {
            checkCudaErrors( cudaEventDestroy( reinterpret_cast<cudaEvent_t>(ptr) ));
        }
    };

    shared_ptr<cudaEvent_t> Allocate( ){
        cudaEvent_t event;
        checkCudaErrors( cudaEventCreate( &event ) );
        shared_ptr<cudaEvent_t> p( reinterpret_cast<cudaEvent_t*>(event), Deleter() );
        return p;
    }

    shared_ptr<cudaEvent_t> ps;

public:
    cudaEvent_t event;

    CudaEvent(  )
    : ps( Allocate( ) ),
      event( *(ps.get()) )
    {   }
};

1 个答案:

答案 0 :(得分:2)

您正在混淆两个独立的机制:CUDA事件的RAII类和使用共享指针的生命周期管理。这些应该是完全分开的。

另一个问题是它不清楚你的&#34; checkCudaErrors&#34;应该做的。

最后一个问题是提到的一个talonmies,如果你的范围/生命周期错误就会发生这种情况。例如 - 您在最后一次引用此事件之前已重置设备。或者 - 您在流上排队此事件,然后将该点放到它上面。因此,通过使用共享指针,您并不能确保安全 - 您必须像对待id一样跟踪事情。事实上,这可能会使事情变得更加困难。

最后,请注意您可以将CUDA运行时API与现代C ++包装器一起使用,具体而言,使用RAII而不是createXYZ()和destroyXYZ():

https://github.com/eyalroz/cuda-api-wrappers

具体来说,您可以查看:

适当披露:我是这个图书馆的作者。