为 CUDA 实现 32 位内存集的"正确"方法是什么?

What's the 'right' way to implement a 32-bit memset for CUDA?

本文关键字:正确 方法 是什么 实现 CUDA 内存      更新时间:2023-10-16

CUDA有API调用

cudaError_t cudaMemset (void *devPtr, int value, size_t count)

用单字节值填充缓冲区。我想用一个多字节的值填充它。为了简单起见,假设我想用一个32位(4字节)的值填充devPtr,并且假设我们可以忽略端序。现在,CUDA驱动程序有以下API调用:

CUresult cuMemsetD32(CUdeviceptr dstDevice, unsigned int ui, size_t N)

所以它足以让我只是:从设备内存空间指针获得CUdeviceptr,然后使驱动程序API调用?还是我还有别的事要做?

从CUDA 3.0开始,运行时API设备指针(以及其他所有东西)都可以与驱动程序API互操作。所以是的,你可以使用cuMemsetD32来填充一个32位值的运行时API分配。CUdeviceptr的大小将匹配void *在您的平台上的大小,它是安全的转换指针从CUDA API到CUdeviceptr,反之亦然

根据talonmies的回答,似乎一个合理的(尽管不美观)方法是:

#include <stdint.h>
inline cudaError_t cudaMemsetTyped<T>(void *devPtr, T value, size_t count);
#define INSTANTIATE_CUDA_MEMSET_TYPED(_nbits) 
inline cudaError_t cudaMemsetTyped<int ## _nbits ## _t>(void *devPtr, int ## _nbits ## _t value, size_t count) { 
    cuMemsetD ## _nbits( reinterpret_cast<CUdeviceptr>(devPtr), value, count); 
} 
inline cudaError_t cudaMemsetTyped<uint ## _nbits ## _t>(void *devPtr, uint ## _nbits ## _t value, size_t count) { 
    cuMemsetD ## _nbits( reinterpret_cast<CUdeviceptr>(devPtr), reinterpret_cast<uint ## _nbits ## _t>(value), count); 
} 
INSTANTIATE_CUDA_MEMSET_TYPED(8)
INSTANTIATE_CUDA_MEMSET_TYPED(16)
INSTANTIATE_CUD_AMEMSET_TYPED(32)
#undef INSTANTIATE_CUDA_MEMSET_TYPED(_nbits)
inline cudaError_t cudaMemsetTyped<float>(void *devPtr, float value, size_t count) {
    cuMemsetD32( reinterpret_cast<CUdeviceptr>(devPtr), reinterpret_cast<int>(value), count);
}

(似乎没有cuMemset64,所以也没有double)