我可以将C++对象复制到设备吗?
说我有:
class CudaClass
{
public:
int* data;
CudaClass(int x) {
data = new int[1]; data[0] = x;
}
};
__global__ void useClass(CudaClass cudaClass)
{
printf("%d" cudaClass.data[0]);
};
int main()
{
CudaClass c(1);
}
Run Code Online (Sandbox Code Playgroud)
现在如何将"c"复制到设备内存并启动内核"useClass"?
我想知道当我分配一个结构然后分配(?)并复制相同结构的指针元素时,设备上发生了什么(内存方面).
我是否还需要cudaMalloc元素*a?
示例代码:
typedef struct {
int *a;
...
} StructA;
int main()
{
int row, col, numS = 10; // defined at runtime
StructA *d_A = (StructA*)malloc(numS * sizeof(StructA));
int *h_A = d_a->a;
cudaMalloc( (void**)&(d_A), numS * sizeof(StructA) );
cudaMalloc( &(d_A->a), row*col*sizeof(int) ); // no (void**) needed?
cudaMemcpy( d_A->a, h_A, row*col*sizeof(int), cudaMemcpyHostToDevice );
kernel<<<grid, block>>>(d_A); // Passing pointer to StructA in device
...
}
Run Code Online (Sandbox Code Playgroud)
内核定义:
__global__ kernel(StructA *d_A)
{
d_A->a = ...;
... …Run Code Online (Sandbox Code Playgroud) 我有一个Parent类和一个继承Child类:
class Parent {};
class Child : public Parent {};
Run Code Online (Sandbox Code Playgroud)
有几个子类继承自Parent,但为了简单起见,我只包含了一个。这些继承的类对于我正在从事的项目是必需的。我还有另一个类的对象,我希望将其复制到设备上:
class CopyClass {
public:
Parent ** par;
};
Run Code Online (Sandbox Code Playgroud)
请注意,之所以Parent ** par;存在,是因为我需要一个Child对象列表,但它将使用哪个子对象(以及列表的长度)在编译时未知。这是我将CopyClass对象复制到设备上的尝试:
int length = 5;
//Instantiate object on the CPU
CopyClass cpuClass;
cpuClass.par = new Parent*[length];
for(int i = 0; i < length; ++i) cpuClass.par[i] = new Child;
//Copy object onto GPU
CopyClass * gpuClass;
cudaMalloc(&gpuClass,sizeof(CopyClass));
cudaMemcpy(gpuClass,&cpuClass,sizeof(CopyClass),cudaMemcpyHostToDevice);
//Copy dynamically allocated variables to GPU
Parent ** …Run Code Online (Sandbox Code Playgroud) 将struct数组传递给gpu内核时遇到问题.我基于这个主题 - cudaMemcpy分段错误,我写了这样的:
#include <stdio.h>
#include <stdlib.h>
struct Test {
char *array;
};
__global__ void kernel(Test *dev_test) {
for(int i=0; i < 5; i++) {
printf("Kernel[0][i]: %c \n", dev_test[0].array[i]);
}
}
int main(void) {
int n = 4, size = 5;
Test *dev_test, *test;
test = (Test*)malloc(sizeof(Test)*n);
for(int i = 0; i < n; i++)
test[i].array = (char*)malloc(size * sizeof(char));
for(int i=0; i < n; i++) {
char temp[] = { 'a', 'b', 'c', 'd' , 'e' };
memcpy(test[i].array, …Run Code Online (Sandbox Code Playgroud) 假设我有这门课程:
class Particle
{
double *_w;
};
Run Code Online (Sandbox Code Playgroud)
我想将nParticles对象发送Particle到我的内核.为这些对象分配空间很简单:
Particle *dev_p;
cudaStatus = cudaMalloc((void**)&dev_P, nParticles * sizeof(Particle));
if (cudaStatus != cudaSuccess) {
fprintf(stderr, "cudaMalloc failed!");
goto Error;
}
Run Code Online (Sandbox Code Playgroud)
还假设 nParticles是100.现在,我需要分配300双为每_w一个Particle对象.我怎样才能做到这一点?我试过这段代码:
for( int i = 0; i < nParticles; i++){
cudaStatus = cudaMalloc((void**)&(dev_P[i]._w), 300 * sizeof(double));
if (cudaStatus != cudaSuccess) {
fprintf(stderr, "cudaMalloc failed!");
goto Error;
}
}
Run Code Online (Sandbox Code Playgroud)
但是当我访问dev_p [i] ._ w [j]时,使用Nsight进行调试会停止.
在线上有很多关于在CUDA上分配,复制,索引等2d和3d数组的问题。我得到了很多矛盾的答案,因此我试图汇编过去的问题,看看我是否可以提出正确的问题。
第一个链接:https : //devtalk.nvidia.com/default/topic/392370/how-to-cudamalloc-two-Dimension-array-/
问题:分配二维指针数组
用户解决方案:使用mallocPitch
“正确”的低效率解决方案:在for循环中为每行使用malloc和memcpy(荒谬的开销)
“更正确”的解决方案:将其压缩为1d数组的“专业意见”,有评论说没有人关注性能,但在gpu上使用2d指针结构
第二个链接:https : //devtalk.nvidia.com/default/topic/413905/passing-a-multiDimension-array-to-kernel-how-to-allocate-space-in-host-and-pass-to-device -/
问题:在主机上分配空间并将其传递给设备
子链接:https : //devtalk.nvidia.com/default/topic/398305/cuda-programming-and-performance/dynamically-allocate-array-of-structs/
子链接解决方案:在GPU上编码基于指针的结构是一种糟糕的体验,并且效率极低,因此将其压缩为一维数组。
第三个链接:在CUDA中的设备内存上分配2D阵列
问题:分配和传输二维数组
用户解决方案:使用mallocPitch
其他解决方案:将其展平
第四个链接:如何在CUDA中使用2D阵列?
问题:分配和遍历二维数组
提交的解决方案:不显示分配
其他解决方案:压扁
还有许多其他消息来源大多在说同样的话,但是在多个实例中,我看到有关GPU上指针结构的警告。
许多人认为分配指针数组的正确方法是为每行调用malloc和memcpy,但函数mallocPitch和memcpy2D存在。这些功能的效率有所降低吗?为什么这不是默认答案?
二维数组的另一个“正确”答案是将它们压缩成一个数组。我是否应该习惯生活中的事实?我对我的代码非常拘谨,对我来说感觉很不雅。
我正在考虑的另一种解决方案是使使用1d指针数组的矩阵类最大化,但是我找不到实现双括号运算符的方法。
还要根据此链接:将对象复制到设备?
和子链接答案:cudaMemcpy分段错误
这有点浮躁。
我想全部使用CUDA的类都具有2 / 3d数组,将这些转换为CUDA的1d数组会不会有很多开销?
我知道我已经问了很多问题,但总的来说,我应该习惯于将数组压缩为现实,还是可以使用二维分配和复制函数而不会产生不好的开销,例如在for中调用alloc和cpy的解决方案中环?
我对这个基本的CUDA代码感到烦恼.
我有一个char**平面的2d密码数组,我目前的实现是CUDA只是迭代这个列表并显示密码.但是,当我去显示它们时,我只是得到"(NULL)".我不太清楚为什么会这样.有人可以解释它发生了什么吗?
主要:
char ** pwdAry;
pwdAry = new char *[numberOfPwd];
//pwdAry given some values (flat 2d array layout)
const int pwdArySize = sizeof(pwdAry);
dim3 grid(gridSize,gridSize);
dim3 block(blockSize,blockSize);
searchKeywordKernel << <grid, block >> >(pwdAry);
return EXIT_SUCCESS;
Run Code Online (Sandbox Code Playgroud)
CUDA:
__global__ void searchKeywordKernel(char **passwordList)
{
int x = threadIdx.x + blockIdx.x * blockDim.x;
int y = threadIdx.y + blockIdx.y * blockDim.y;
int pitch = blockDim.x * gridDim.x;
int idx = x + y * pitch;
int tidy = idx / pitch; …Run Code Online (Sandbox Code Playgroud)