我正在使用 CUDA API/cuFFT API。为了将数据从主机移动到 GPU,我使用了 cudaMemcpy 函数。我正在像下面这样使用它。 len 是 dataReal 和 dataImag 上的元素数量。
void foo(const double* dataReal, const double* dataImag, size_t len)
{
cufftDoubleComplex* inputData;
size_t allocSizeInput = sizeof(cufftDoubleComplex)*len;
cudaError_t allocResult = cudaMalloc((void**)&inputData, allocSizeInput);
if (allocResult != cudaSuccess) return;
cudaError_t copyResult;
coypResult = cudaMemcpy2D(static_cast<void*>(inputData),
2 * sizeof (double),
static_cast<const void*>(dataReal),
sizeof(double),
sizeof(double),
len,
cudaMemcpyHostToDevice);
coypResult &= cudaMemcpy2D(static_cast<void*>(inputData) + sizeof(double),
2 * sizeof (double),
static_cast<const void*>(dataImag),
sizeof(double),
sizeof(double),
len,
cudaMemcpyHostToDevice);
//and so on.
}
我知道,空指针上的指针运算实际上是不可能的。第二个 cudaMemcpy2D 仍然有效。我仍然收到编译器的警告,但它工作正常。
我尝试使用 static_cast< char* > 但它不起作用,因为 cuffDoubleComplex* 不能静态转换为 char*。
我有点困惑,为什么第二个 cudaMemcpy 与 void 上的指针算法正在工作,据我所知它不应该。编译器是否隐含地假设 void* 后面的数据类型是一个字节长?
我应该在那里改变什么吗?例如使用 reinterpret_cast< char* >(inputData)?
在分配期间,我还在使用旧的 C 风格 (void**) 转换。我这样做是因为我收到“从 cufftDoubleComplex** 到 void** 的无效 static_cast”。还有其他方法可以正确执行此操作吗?
最佳答案
你不能对 void*
进行算术运算,因为对指针的算术运算是基于指向对象的大小(而 sizeof(void)
并没有真正的意义).
您的代码编译可能要归功于编译器扩展,该扩展将 void*
上的算术运算视为 char*
上的算术运算。
在您的情况下,您可能不需要算术运算,以下应该有效(并且更健壮):
coypResult &= cudaMemcpy2D(static_cast<void*>(&inputData->y),
sizeof (cufftDoubleComplex),
因为 cufftDoubleComplex
很简单:
struct __device_builtin__ __builtin_align__(16) double2
{
double x, y;
};
关于c++ - void* 指针的指针运算,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38047908/