• Cuda learn record three


    1. 页锁定 主机内存

    通过malloc分配的主机内存是可分页的(pagable),而cudaHostAlloc要分配页锁定的主机内存,即固定内存。GPU可以直接内存访问。

    但是,使用页锁定内存时,操作系统的虚拟内存的功能将失效,程序可能会快速的耗尽系统内存,这一方面可能导致程序因内存不足而运行失败,另一方面,也会使其他正在使用的程序的效率受损。

    固定内存是一把双刃剑。使用页锁定时,不需要该内存时,及时的释放掉该内存。cudaFreeHost()

    当系统的PCIE总线带宽受到限制的时候,使用页锁定内存可以有效的加速程序。

    2. CUDA 流

    以异步方式只能对页锁定内存进行复制操作。

    异步操作只能保证会在下一个被放入流中的程序之前执行,但不能保证返回时已经运行结束。

     3. cuda中很少使用2维以上的指针,这与cuda本身在内存中的复制有关。

    但是我们可以使用一维线性的内存空间来模拟二维甚至三维的数组。

    下面这个地址详细的介绍了二维和三维类型的数组的申请方法。

    http://www.cnblogs.com/traceorigin/archive/2013/04/11/3015554.html

    或者是,

    http://blog.csdn.net/augusdi/article/details/12187091

    4. 对于C语言中memset()函数的认识。

    该函数的原型是void *memset(void *s, int ch, size_t n);

    但是要注意到的一点是,该函数对于非字符型的数组,只能赋0或者-1,其他的赋值都会出问题。这是因为该函数采用的赋值的方式是逐个字节的赋值。

    5. 考察了C语言用指针生成二维动态数组的方法。

     1 template<typename T>
     2 T** createArray(T b, int m, int n)
     3 {
     4     T ** p = (T **)malloc(m * sizeof(T*));
     5     assert(p != NULL);
     6     T* q = (T *)malloc(m*n * sizeof(T));
     7     assert(q != NULL);
     8     memset(q, (T)0, m*n * sizeof(T));
     9     //printf("%d@@", sizeof(q));
    10     for (int i = 0; i != m; ++i) {
    11         p[i] = i*n+q;
    12     }
    13     for (int i = 0; i != m; ++i) {
    14         for (int j = 0; j != n; ++j) {
    15             p[i][j] = 2;
    16         }
    17     }
    18     return p;
    19 }
    20 
    21 template<typename T>
    22 void deleteArray(T** p) {
    23     free((void*)p[0]);
    24     p[0] = NULL;
    25     free((void*) p);
    26     p = NULL;
    27 }

    //下面是另一种实现的方法

    template<typename T>
    void allocMatrix(T*** pointer, int m, int n)
    {
    (*pointer) = (T **)malloc((m + 1) * sizeof(T *));
    if ((*pointer) == nullptr) {
    printf("内存空间不足,无法申请二维数组! ");
    exit(1);
    }
    for (int i = 0; i <= m; ++i) {
    (*pointer)[i] = (T*)malloc((n + 1) * sizeof(T));
    if ((*pointer)[i] == nullptr) {
    printf("内存空间不足,无法申请二维数组! ");
    exit(1);
    }
    }
    }

    template<typename T>
    void deleteMatrix(T ** &p, int m) {
    for (int i = m; i >= 0; --i) {
    free(p[i]);
    p[i] = nullptr;
    }
    free(p);
    p = nullptr;
    }

    实现了一段在host端使用二维数组,在device端使用一维数组的程序

     1     int temp = 0;
     2     //int *host_a =(int *) malloc(5 * 5 * sizeof(int));
     3     int **host_a = createArray(temp, 5, 5);
     4     for (int i = 0; i != 5; ++i) {
     5         for (int j = 0; j != 5; ++j) {
     6             host_a[i][j] = 1;
     7         }
     8     }
     9     int *dev_a = NULL;
    10     int *h_a = host_a[0];
    11     for (int i = 0; i != 5; ++i) {
    12         for (int j = 0; j != 5; ++j) {
    13             cout << h_a[i * 5 + j]<<" ";
    14         }
    15         cout << endl;
    16     }
    17     HANDLE_ERROR(cudaMalloc((void**)& dev_a, 5 * 5 * sizeof(int)));
    18     HANDLE_ERROR(cudaMemcpy( dev_a, *host_a, 5 * 5 * sizeof(int), cudaMemcpyHostToDevice));
    19 
    20     dim3 threads(5, 5);
    21     kernel << <1, threads >> > (dev_a);
    22 
    23     HANDLE_ERROR(cudaMemcpy(*host_a, dev_a, 5 * 5 * sizeof(int), cudaMemcpyDeviceToHost));
    24 
    25     for (int i = 0; i != 5; ++i) {
    26         for (int j = 0; j != 5; ++j) {
    27             cout << h_a[i * 5 + j] << " ";
    28         }
    29         cout << endl;
    30     }
    31 
    32     free(host_a);
    33     HANDLE_ERROR(cudaFree(dev_a));
  • 相关阅读:
    bzoj1098: [POI2007]办公楼biu
    codeforce1070 2018-2019 ICPC, NEERC, Southern Subregional Contest (Online Mirror, ACM-ICPC Rules, Teams Preferred) 题解
    南京大学发布无序列限制的DNA编辑新工具(转自生物通)
    Matlab界面清洗
    二硫化铼(ReS2)的电子输运特性及逻辑器件研究进展
    java中数据字典的使用:
    表单的重复提交,解决方案
    java中常量文件的配置与读取
    java中生成验证码,以及验证码的使用
    邮箱验证,工具类
  • 原文地址:https://www.cnblogs.com/cofludy/p/6929515.html
Copyright © 2020-2023  润新知