CUDA上的二维阵列

CUDA上的二维阵列,c,cuda,C,Cuda,我想在CUDA中动态分配全局2D数组。我怎样才能做到这一点 我主要是在循环中调用我的内核。但是在调用内核之前,我需要在GPU上分配一些内存。内核调用后,从GPU向CPU发送一个整数,通知问题是否得到解决。 如果问题没有解决,我将不会释放旧内存,因为还需要它,我应该将新内存分配给GPU,然后再次调用内核 显示了一个sudocode: int n=0,i=0; while(n==0) { //allocate 2d memory for MEM[i++] //call kernel

我想在
CUDA
中动态分配全局
2D
数组。我怎样才能做到这一点

我主要是在循环中调用我的
内核。但是在调用内核之前,我需要在
GPU
上分配一些内存。内核调用后,从GPU向CPU发送一个整数,通知问题是否得到解决。
如果问题没有解决,我将不会释放旧内存,因为还需要它,我应该将新内存分配给
GPU
,然后再次调用内核

显示了一个sudocode:

int n=0,i=0;
while(n==0)
{
    //allocate 2d memory for MEM[i++] 
    //call kernel(MEM,i)
    // get n from kernel       
}


__global__ void kernerl(Mem,int i)
{
    Mem[0][5]=1;
    Mem[1][0]=Mem[0][5]+23;//can use this when MEM[1] is allocated before kernel call
}

有什么建议吗?谢谢。

编辑:
我试图帮助您提供一个示例,在该示例中,通过展平阵列,您可以获得相同的结果,但mates告诉我这不是您想要的。

因此,还有一篇帖子告诉您如何在CUDA中分配2d数组。

编辑:
我试图帮助您提供一个示例,在该示例中,通过展平阵列,您可以获得相同的结果,但mates告诉我这不是您想要的。

因此,还有一篇帖子告诉你如何在CUDA中分配2d数组。

两条开场白-在CUDA中使用动态分配的2d数组是个坏主意,在循环中重复分配内存也不是个好主意。两者都会招致不必要的性能惩罚

对于主机代码,如下所示:

size_t allocsize = 16000 * sizeof(float);
int n_allocations = 16;
float * dpointer
cudaMalloc((void **)&dpointer, n_allocations * size_t(allocsize));

float * dcurrent = dpointer;
int n = 0;
for(int i=0; ((n==0) && (i<n_allocations)); i++, dcurrent+=allocsize) {

    // whatever you do before the kernel

    kernel <<< gridsize,blocksize >>> (dcurrent,.....);

    // whatever you do after the kernel

}
__global__ void kernel(float *Mem, int lda, int this, int previous)
{
   float * Mem0 = Mem + this;
   float * Mem1 = Mem + previous;

}
它使用索引到1D分配中。在GPU中,内存事务非常昂贵,但触发器和IOPS很便宜。单整数乘加是最有效的方法。如果需要访问前一个内核调用的结果,只需将偏移量传递给前一个结果,并在内核中使用两个指针,如下所示:

size_t allocsize = 16000 * sizeof(float);
int n_allocations = 16;
float * dpointer
cudaMalloc((void **)&dpointer, n_allocations * size_t(allocsize));

float * dcurrent = dpointer;
int n = 0;
for(int i=0; ((n==0) && (i<n_allocations)); i++, dcurrent+=allocsize) {

    // whatever you do before the kernel

    kernel <<< gridsize,blocksize >>> (dcurrent,.....);

    // whatever you do after the kernel

}
__global__ void kernel(float *Mem, int lda, int this, int previous)
{
   float * Mem0 = Mem + this;
   float * Mem1 = Mem + previous;

}
高效的分布式内存程序(CUDA实际上是一种分布式内存编程)在一段时间后开始看起来像Fortran,但这是您为可移植性、透明度和效率付出的代价


希望这能有所帮助。

两条开场白-在CUDA中使用动态分配的2D数组是个坏主意,在循环中重复分配内存也不是个好主意。两者都会招致不必要的性能惩罚

对于主机代码,如下所示:

size_t allocsize = 16000 * sizeof(float);
int n_allocations = 16;
float * dpointer
cudaMalloc((void **)&dpointer, n_allocations * size_t(allocsize));

float * dcurrent = dpointer;
int n = 0;
for(int i=0; ((n==0) && (i<n_allocations)); i++, dcurrent+=allocsize) {

    // whatever you do before the kernel

    kernel <<< gridsize,blocksize >>> (dcurrent,.....);

    // whatever you do after the kernel

}
__global__ void kernel(float *Mem, int lda, int this, int previous)
{
   float * Mem0 = Mem + this;
   float * Mem1 = Mem + previous;

}
它使用索引到1D分配中。在GPU中,内存事务非常昂贵,但触发器和IOPS很便宜。单整数乘加是最有效的方法。如果需要访问前一个内核调用的结果,只需将偏移量传递给前一个结果,并在内核中使用两个指针,如下所示:

size_t allocsize = 16000 * sizeof(float);
int n_allocations = 16;
float * dpointer
cudaMalloc((void **)&dpointer, n_allocations * size_t(allocsize));

float * dcurrent = dpointer;
int n = 0;
for(int i=0; ((n==0) && (i<n_allocations)); i++, dcurrent+=allocsize) {

    // whatever you do before the kernel

    kernel <<< gridsize,blocksize >>> (dcurrent,.....);

    // whatever you do after the kernel

}
__global__ void kernel(float *Mem, int lda, int this, int previous)
{
   float * Mem0 = Mem + this;
   float * Mem1 = Mem + previous;

}
高效的分布式内存程序(CUDA实际上是一种分布式内存编程)在一段时间后开始看起来像Fortran,但这是您为可移植性、透明度和效率付出的代价


希望这能有所帮助。

好吧,您可以像在CPU上一样完成它

unsigned xSize = 666, ySize = 666;
int **h_ptr = (int**)malloc(sizeof(int*) * xSize);
int **d_ptr = NULL;
cudaMalloc( &d_ptr, xSize );
for(unsigned i = 0; i < xSize; ++i)
{
    cudaMalloc( &h_ptr[i], ySize );
}
cudaMemcpy( &d_ptr, &h_ptr, sizeof(int*) * xSize, cudaMemcpyHostToDevice );
free( h_ptr );
unsignedxsize=666,ySize=666;
int**h_ptr=(int**)malloc(sizeof(int*)*xSize);
int**d_ptr=NULL;
cudaMalloc(&d_ptr,xSize);
for(无符号i=0;i
……同样自由

int **h_ptr = (int**)malloc(sizeof(int*) * xSize);
cudaMemcpy( &h_ptr, &d_ptr, sizeof(int*) * xSize, cudaMemcpyDeviceToHost );
for(unsigned i = 0; i < xSize; ++i )
{
    cudaFree( h_ptr[i] );
}
cudaFree( d_ptr );
free( h_ptr );
int**h_ptr=(int**)malloc(sizeof(int*)*xSize);
cudaMemcpy(&h_ptr和&d_ptr,sizeof(int*)*xSize,cudaMemcpyDeviceToHost);
for(无符号i=0;i

但您应该记住,对该阵列单元的每次访问都将涉及两次访问GPU全局内存。因此,内存访问速度将比使用1d阵列慢两倍。

好吧,您可以像在CPU上一样执行此操作

unsigned xSize = 666, ySize = 666;
int **h_ptr = (int**)malloc(sizeof(int*) * xSize);
int **d_ptr = NULL;
cudaMalloc( &d_ptr, xSize );
for(unsigned i = 0; i < xSize; ++i)
{
    cudaMalloc( &h_ptr[i], ySize );
}
cudaMemcpy( &d_ptr, &h_ptr, sizeof(int*) * xSize, cudaMemcpyHostToDevice );
free( h_ptr );
unsignedxsize=666,ySize=666;
int**h_ptr=(int**)malloc(sizeof(int*)*xSize);
int**d_ptr=NULL;
cudaMalloc(&d_ptr,xSize);
for(无符号i=0;i
……同样自由

int **h_ptr = (int**)malloc(sizeof(int*) * xSize);
cudaMemcpy( &h_ptr, &d_ptr, sizeof(int*) * xSize, cudaMemcpyDeviceToHost );
for(unsigned i = 0; i < xSize; ++i )
{
    cudaFree( h_ptr[i] );
}
cudaFree( d_ptr );
free( h_ptr );
int**h_ptr=(int**)malloc(sizeof(int*)*xSize);
cudaMemcpy(&h_ptr和&d_ptr,sizeof(int*)*xSize,cudaMemcpyDeviceToHost);
for(无符号i=0;i

但您应该记住,对该阵列单元的每次访问都将涉及两次访问GPU全局内存。因此,内存访问速度将是1d数组的两倍。

在CUDA中,分配2D数组就像分配1d数组一样,因为在许多内核中,您可以在内存中看到普通1d数组。。。为什么要投反对票?!?我试图帮助她……在CUDA中,可以使用cudaMallocPitch和cudaMemcpy2D分配2d阵列。但我不能回答这个问题,因为我不确定这是否可以在循环中完成…@scatman:你是对的,我知道,但我只是想帮助她告诉她,你可以分配一个2D数组,就像分配一个使用不同维度的一维数组一样。你可以在内核中随心所欲地使用它。@scatman,@Ghyath:我编辑了我的帖子删除示例,即使我认为她可以使用它。希望这能帮她多一点。@scatman:cudamallocpatch不分配2D数组。它只分配一个线性内存分配,该分配计算了填充,以便与GPU纹理硬件配合使用。CUDA中没有API可以“自动”分配指针的动态C数组,每个数组条目也分配给请求的大小。在CUDA中,分配2D数组就像分配1D数组一样,因为在许多内核中,您可以在内存中看到普通1D数组一样。。。为什么要投反对票?!?我试图帮助她……在CUDA中,可以使用cudaMallocPitch和cudaMemcpy2D分配2d阵列。但我不能