Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C GPU上结构动态数组的内存分配_C_Struct_Cuda_Dynamic Memory Allocation - Fatal编程技术网

C GPU上结构动态数组的内存分配

C GPU上结构动态数组的内存分配,c,struct,cuda,dynamic-memory-allocation,C,Struct,Cuda,Dynamic Memory Allocation,我在将结构数组传递到gpu内核时遇到问题。我是基于这个主题写的,我写了这样的东西: #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

我在将结构数组传递到gpu内核时遇到问题。我是基于这个主题写的,我写了这样的东西:

#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, temp, size * sizeof(char));
    }

    cudaMalloc((void**)&dev_test, n * sizeof(Test));
    cudaMemcpy(dev_test, test, n * sizeof(Test), cudaMemcpyHostToDevice);
    for(int i=0; i < n; i++) {
        cudaMalloc((void**)&(test[i].array), size * sizeof(char));
        cudaMemcpy(&(dev_test[i].array), &(test[i].array), size * sizeof(char), cudaMemcpyHostToDevice);
    }

    kernel<<<1, 1>>>(dev_test);
    cudaDeviceSynchronize();

    //  memory free
    return 0;
}
#包括
#包括
结构测试{
字符*数组;
};
__全局无效内核(测试*开发测试){
对于(int i=0;i<5;i++){
printf(“内核[0][i]:%c\n”,开发测试[0]。数组[i]);
}
}
内部主(空){
int n=4,size=5;
测试*开发测试,*测试;
测试=(测试*)malloc(sizeof(测试)*n);
对于(int i=0;i
没有错误,但内核中显示的值不正确。我做错了什么?提前感谢您的帮助

  • 这将为主机内存分配一个新指针:

     test[i].array = (char*)malloc(size * sizeof(char));
    
     memcpy(test[i].array, temp, size * sizeof(char));
    
  • 这是将数据复制到主机内存中的该区域:

     test[i].array = (char*)malloc(size * sizeof(char));
    
     memcpy(test[i].array, temp, size * sizeof(char));
    
  • 这将使用指向设备内存的新指针覆盖先前分配给主机内存的指针(从上面的步骤1开始):

     cudaMalloc((void**)&(test[i].array), size * sizeof(char));
    
  • 在步骤3之后,您在步骤2中设置的数据将完全丢失,并且不再以任何方式访问。参考链接中的步骤3和步骤4:

    3.在主机上创建一个单独的int指针,我们称之为
    myhostptr

    4.myhostptr设备上的cudaMalloc int存储

    你没有这样做。您没有创建单独的指针。您重新使用(擦除、重写)了一个现有指针,该指针指向您在主机上关心的数据,同样从您链接的答案链接,以代码形式给出了您需要遵循的步骤

    下面是代码的修改版本,根据链接的问题/答案,它正确地实现了缺少的步骤3和4(以及5)(请参阅描述步骤3、4、5的注释)

    当然,我们认识到,这种特殊的方法并不能满足所有的目的,但它应该说明一般的想法/意图。例如,通过该修改,代码变得更加简单:

    $ cat t755.cu
    #include <stdio.h>
    #include <stdlib.h>
    
    struct Test {
        char array[5];
    };
    
    __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++) {
            char temp[] = { 'a', 'b', 'c', 'd' , 'e' };
            memcpy(test[i].array, temp, size * sizeof(char));
        }
    
        cudaMalloc((void**)&dev_test, n * sizeof(Test));
        cudaMemcpy(dev_test, test, n * sizeof(Test), cudaMemcpyHostToDevice);
    
        kernel<<<1, 1>>>(dev_test);
        cudaDeviceSynchronize();
    
        //  memory free
        return 0;
    }
    $ nvcc -o t755 t755.cu
    $ cuda-memcheck ./t755
    ========= CUDA-MEMCHECK
    Kernel[0][i]: a
    Kernel[0][i]: b
    Kernel[0][i]: c
    Kernel[0][i]: d
    Kernel[0][i]: e
    ========= ERROR SUMMARY: 0 errors
    $
    
    $cat t755.cu
    #包括
    #包括
    结构测试{
    字符数组[5];
    };
    __全局无效内核(测试*开发测试){
    对于(int i=0;i<5;i++){
    printf(“内核[0][i]:%c\n”,开发测试[0]。数组[i]);
    }
    }
    内部主(空){
    int n=4,size=5;
    测试*开发测试,*测试;
    测试=(测试*)malloc(sizeof(测试)*n);
    对于(int i=0;i
    为什么是
    cudamaloc((void**)和(test[i].array),size*sizeof(char))而非
    cudamaloc((void**)和(dev_test[i].array),size*sizeof(char))?另外,它应该是
    cudaMemcpy(dev_test[i]。数组,test[i]。数组,size*sizeof(char),cudamemcpyhostodevice)@francis,它不工作(分段故障(堆芯转储))。在gpu上,我们不能以标准方式分配内存。另外一个友好的建议:不要从问题中选择代码,除非你已经理解了提问者面临的问题…如果我的建议不起作用,很抱歉。我的建议是为
    dev_test[i].array
    分配内存,而不是为
    test[i].array
    分配内存,后者已由
    test[i]在CPU上分配。array=(char*)malloc(size*sizeof(char))@francis,好的,没问题。是
    测试[i]。阵列
    已分配,但仅在CPU上分配,在GPU上不分配。我们无法为
    dev_test[i].array分配内存,因为此内存仅从设备可见。至少我是这样理解的。非常感谢。“扁平化数据结构”是什么意思?更新了我的答案以回答这个问题。然而,如果你在CUDA标签上搜索,你会发现很多关于“扁平化”的参考和例子。