如何将设备内存中分配的结构化数据从设备复制到主机
How to copy structured data allocated in device memory from device to host
我是GPU和CUDA编程的新手。我正在尝试将设备上动态分配的结构化数据从设备复制到主机。我修改了 GPU 编程指南中的简单代码。我在编译代码时没有收到任何错误,但我唯一有问题的是输出是错误的,即"0"。代码如下:
#include <stdlib.h>
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <stdio.h>
typedef struct Point
{
int2 pt;
};
#define NUMOFBLOCKS 1
#define THREDSPERBLOCK 16
__device__ Point* pnt[NUMOFBLOCKS];
Point dataptr_h[NUMOFBLOCKS][THREDSPERBLOCK];
__global__ void allocmem()
{
if (threadIdx.x == 0)
pnt[blockIdx.x] = (Point*)malloc(1*blockDim.x * sizeof(Point));
__syncthreads();
}
__global__ void usemem()
{
Point* ptr = pnt[blockIdx.x];
if (ptr != NULL)
{
ptr[threadIdx.x].pt.x = threadIdx.x;
ptr[threadIdx.x].pt.y = threadIdx.x;
printf("Ptr = %dt", ptr[threadIdx.x].pt.x);
}
}
__global__ void freemem()
{
Point* ptr = pnt[blockIdx.x];
if (ptr != NULL)
printf("Block %d, Thread %d: final value = %dn", blockIdx.x, threadIdx.x, ptr[threadIdx.x]);
if (threadIdx.x == 0)
free(ptr);
}
int main()
{
Point* d_pt[NUMOFBLOCKS];
for (int i = 0 ; i < NUMOFBLOCKS; i++)
cudaMalloc(&d_pt[i], sizeof(Point)*16);
// Allocate memory
allocmem<<< NUMOFBLOCKS, THREDSPERBLOCK >>>();
// Use memory
usemem<<< NUMOFBLOCKS, THREDSPERBLOCK >>>();
cudaMemcpyFromSymbol(d_pt, pnt, sizeof(d_pt));
cudaMemcpy(dataptr_h, d_pt, sizeof(dataptr_h), cudaMemcpyDeviceToHost);
for (int j = 0 ; j < 1; j++)
for (int i = 0 ; i < 16; i++)
{
printf("nPtr_h(%d,%d)->X = %dt", j, i, dataptr_h[j][i].pt.x);
printf("Ptr_h(%d,%d)->Y = %d", j, i, dataptr_h[j][i].pt.y);
}
freemem<<< NUMOFBLOCKS, THREDSPERBLOCK >>>();
cudaDeviceSynchronize();
return 0;
}
代码的输出为:
Ptr_h(0,0)->X = 0 Ptr_h(0,0)->Y = 0
Ptr_h(0,1)->X = 0 Ptr_h(0,1)->Y = 0
Ptr_h(0,2)->X = 0 Ptr_h(0,2)->Y = 0
Ptr_h(0,3)->X = 0 Ptr_h(0,3)->Y = 0
Ptr_h(0,4)->X = 0 Ptr_h(0,4)->Y = 0
Ptr_h(0,5)->X = 0 Ptr_h(0,5)->Y = 0
Ptr_h(0,6)->X = 0 Ptr_h(0,6)->Y = 0
Ptr_h(0,7)->X = 0 Ptr_h(0,7)->Y = 0
Ptr_h(0,8)->X = 0 Ptr_h(0,8)->Y = 0
Ptr_h(0,9)->X = 0 Ptr_h(0,9)->Y = 0
Ptr_h(0,10)->X = 0 Ptr_h(0,10)->Y = 0
Ptr_h(0,11)->X = 0 Ptr_h(0,11)->Y = 0
Ptr_h(0,12)->X = 0 Ptr_h(0,12)->Y = 0
Ptr_h(0,13)->X = 0 Ptr_h(0,13)->Y = 0
Ptr_h(0,14)->X = 0 Ptr_h(0,14)->Y = 0
Ptr_h(0,15)->X = 0 Ptr_h(0,15)->Y = 0
我该怎么做才能解决这个问题?
您不能将设备创建的指针用于 CUDA 运行时 API malloc
操作(即 cudaMemcpy
)
所以这行代码是有问题的:
cudaMemcpy(dataptr_h, d_pt, sizeof(dataptr_h), cudaMemcpyDeviceToHost);
d_pt
包含从pnt
中获取的指针。 pnt
通过设备malloc
设置了它的值。
相反,您需要创建使用 cudaMalloc
正确分配的区域,然后首先将所需的数据复制到这些区域(从设备上的一个区域复制到另一个区域),然后使用 cudaMemcpy
复制到主机。
我进一步解释您的下一个反对意见之前,让我们明确上述内容是您的意图(使用在设备malloc
操作中创建的指针作为cudaMemcpy
的目标之一)。 这是不合法的。
"可是我用cudaMalloc
??"
d_pt
是驻留在主机内存中的指针数组。 您获取了这些指针中的每一个,并使用 cudaMalloc
为其分配了一个值(设备内存中的指向位置)。
然后这行代码:
cudaMemcpyFromSymbol(d_pt, pnt, sizeof(d_pt));
覆盖了使用从设备内存中其他位置获取的指针设置的所有指针,特别是设备 malloc
分配的指针。 虽然这在技术上是合法的(该行代码不会引发错误),但这些指针在主机上毫无用处(无论如何,用于运行时 API)。
相关文章:
- 矢量如何将数据复制到另一个矢量?
- 将矢量的数据复制到<MyStruct>矢量<MyStruct>的指针
- 将父类的子类的数据复制到具有相同父类的另一个类
- 使用 memcpy 将矢量数据复制到 wstring 的正确方法
- C++:传递指向函数中类的指针会导致数据复制?
- 将数据复制到磁盘上新位置的语法
- pybind11:如何包装以 std::vector<double> 为参数以避免数据复制的 C++ 函数
- 如何将数据复制到字节数组的某些部分
- 使用Sapera拍摄图像并将数据复制到矢量
- 如果strncpy将随机数据复制到缓冲区中会发生什么
- C++ 促进序列化、构造函数和数据复制
- 将一个通道数据复制到OpenCV中的另一个通道
- SSE将数据复制到变量
- doxygen将doxygen注释中的特定数据复制到markdown页面中
- 正在将指针指向的数据复制到另一个指针中
- 使用 CUDA 将大数据复制到 GPU 和从 GPU 复制大数据
- 尝试将.csv数据复制到c++中的结构时出现堆栈溢出错误
- 数据复制与封装
- 如何将 frontBuffer 数据复制到纹理 DirectX 9
- 更快地将数组中的数据复制到目标,同时应用缩放或偏移因子