c++ - void* 指针的指针运算

标签 c++ pointers cuda pointer-arithmetic

我正在使用 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”。还有其他方法可以正确执行此操作吗?

仅供引用:Link to cudaMemcpy2D Doc

Link to cudaMalloc Doc

最佳答案

你不能对 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/

相关文章:

c++ - cin.getline() 跳过

c++ - const std::shared_ptr<const T> 作为函数的参数最终会改变智能指针中类的值

C++ 创建一个每个节点超过 2 个字段的链表

c - 使用 C 返回数组

cuda - CUDA 如何在屏障和条件表达式处精确同步扭曲中的线程?

cuda - 何时将 volatile 与寄存器/局部变量一起使用

c++ - 在一个 C++ 程序中有不同的新运算符 : How to? 坏主意?

c++ - QtCreator/GDB 调试器 : not accessible, 或 `this` 对象未显示

c++ - 初始化列表中的 QString 导致访问冲突。这里出了什么问题?

c - 通过显式算术计算元素指针是否有效?