cudaMalloc和cudaMallocPitch

原文链接

偶有兴趣测试了一下题目中提到的这两个函数,为了满足对齐访问数据,咱们平时可能会用到cudamallocPitch,以为它会带来更高的效率。呵呵,这里给出一段测试程序,大家可以在自己的机器上跑跑,你会发现这两个函数在某些情况下是一样的。

[cpp] view plaincopy

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <cuda_runtime_api.h>
  4. int main(int argc, char **argv)
  5. {
  6. // device pointers.
  7. float *d_pitch;
  8. float *d_normal;
  9. // matrix size.
  10. size_t cols = 63;
  11. size_t rows = 16;
  12. size_t pitch = 0;
  13. // alloc the data form gpu memory.
  14. cudaMallocPitch((void**)&d_pitch, &pitch, cols*sizeof(float), rows);
  15. cudaMalloc((void**)(&d_normal), rows*cols*sizeof(float));
  16. // test the data address.
  17. fprintf(stdout, "row size(in bytes) = %.2f*128.\n", pitch/128.0f);
  18. fprintf(stdout, "the head address of d_pitch  mod 128 = %x.\n", ((unsigned int)d_pitch)%128);
  19. fprintf(stdout, "the head address of d_normal mod 128 = %x.\n", ((unsigned int)d_normal)%128);
  20. cudaFree(d_pitch);
  21. cudaFree(d_normal);
  22. getchar();
  23. return 0;
  24. }

上面这段程序的运行结果如下:

[cpp] view plaincopy

  1. row size(in bytes) = 28.00*128.
  2. the head address of d_pitch mod 128 = 0.
  3. the head address of d_normal mod 128 = 0.

我多次做过实验,我觉得从以上实验结果可以知道,无论如何改变实验的参数,两个显存申请函数返回的数据首地址都是128,256的整数倍,我猜想GPU上的每个计算单元的数据在全局中加载的时候一次可以连续加载2的幂次个数据,并且这些数据的加载其实地址一定也是2的幂次,所以warp使用全局内存中的数据的时候应该尽量按照对齐的原则加载数据,这样就可以获得更高的效率了。至于对齐原则可以在CUDA的编程手册中找到。

时间: 2024-08-28 03:13:25

cudaMalloc和cudaMallocPitch的相关文章

CUDA线性内存分配

原文链接 概述:线性存储器可以通过cudaMalloc().cudaMallocPitch()和cudaMalloc3D()分配 1.1D线性内存分配 1 cudaMalloc(void**,int) //在设备端分配内存 2 cudaMemcpy(void* dest,void* source,int size,enum direction) //数据拷贝 3 cudaMemcpyToSymbol //将数据复制到__constant__变量中,或者__device__变量中 4 cudaMe

CUDA编程

目录: 1.什么是CUDA 2.为什么要用到CUDA 3.CUDA环境搭建 4.第一个CUDA程序 5. CUDA编程 5.1. 基本概念 5.2. 线程层次结构 5.3. 存储器层次结构 5.4. 运行时API 5.4.1. 初始化 5.4.2. 设备管理 5.4.3. 存储器管理 5.4.3.1. 共享存储器 5.4.3.2. 常量存储器 5.4.3.3. 线性存储器 5.4.3.4. CUDA数组 5.4.4. 流管理 5.4.5. 事件管理 5.4.6. 纹理参考管理 5.4.6.1.

cudaMallocPitch – 向GPU分配存储器

概要 cudaError_t cudaMallocPitch( void** devPtr,size_t* pitch,size_t widthInBytes,size_t height ) 说明 向设备分配至少widthInBytes*height字节的线性存储器,并以*devPtr的形式返回指向所分配存储器的指针.该函数可以填充所分配的存储器,以确保在地址从一行更新到另一行时,给定行的对应指针依然满足对齐要求.cudaMallocPitch()以*pitch的形式返回间距,即所分配存储器的宽

二维数组 cudaMallocPitch() 和三维数组 cudaMalloc3D() 的使用

? 使用  cudaMallocPitch()  和配套的  cudaMemcpy2D()  来使用二维数组.C 中二维数组内存分配是转化为一维数组,连贯紧凑,每次访问数组中的元素都必须从数组首元素开始遍历:而 cuda 中这样分配的二维数组内存保证了数组每一行首元素的地址值都按照 256 或 512 的倍数对齐,提高访问效率,但使得每行末尾元素与下一行首元素地址可能不连贯,使用指针寻址时要注意考虑尾部. 1 // cuda_rumtime_api.h 2 extern __host__ cud

gpu显存(全局内存)在使用时数据对齐的问题

全局存储器,即普通的显存,整个网格中的任意线程都能读写全局存储器的任意位置. 存取延时为400-600 clock cycles  非常容易成为性能瓶颈. 访问显存时,读取和存储必须对齐,宽度为4Byte.如果没有正确的对齐,读写将被编译器拆分为多次操作,降低访存性能. 多个warp的读写操作如果能够满足合并访问,则多次访存操作会被合并成一次完成.合并访问的条件,1.0和1.1的设备要求较严格,1.2及更高能力的设备上放宽了合并访问的条件. 1.2及其更高能力的设备支持对8 bit.16 bit

并行程序设计---cuda memory

CUDA存储器模型: GPU片内:register,shared memory: host 内存: host memory, pinned memory. 板载显存:local memory,constant memory, texture memory, texture memory,global memory; register: 訪问延迟极低: 基本单元:register file (32bit/each) 计算能力1.0/1.1版本号硬件:8192/SM. 计算能力1.2/1.3版本号硬

CUDA内存拷贝

原文链接1.cudaMemcpy()<--> cudaMalloc()  //线性内存拷贝 1 //线性内存拷贝 2 cudaMalloc((void**)&dev_A, data_size); 3 cudaMemcpy(dev_A, host_A, data_size, cudaMemcpyHostToDevice); 2.cudaMemcpy2D()<-->cudaMallocPitch() //线性内存拷贝 cudaError_t cudaMemcpy2D( void

CUDA 纹理内存

原文链接 1.概述 纹理存储器中的数据以一维.二维或者三维数组的形式存储在显存中,可以通过缓存加速访问,并且可以声明大小比常数存储器要大的多. 在kernel中访问纹理存储器的操作称为纹理拾取(texture fetching).将显存中的数据与纹理参照系关联的操作,称为将数据与纹理绑定(texture binding). 显存中可以绑定到纹理的数据有两种,分别是普通的线性存储器和cuda数组. 注:线性存储器只能与一维或二维纹理绑定,采用整型纹理拾取坐标,坐标值与数据在存储器中的位置相同:  

二维数组的传输 (host &lt;-&gt; device)

前言 本文的目的很明确:介绍如何将二维数组传递进显存,以及如何将二维数组从显存传递回主机端. 实现步骤 1. 在显存中为二维数组开辟空间 2. 获取该二维数组在显存中的 pitch 值 (cudaMallocPitch 实现) 3. 将二维数组传递进显存 (cudaMemcpy2D 实现) 4. 在显存中对该二维数组进行处理 (目前必须按照 1 维数组的规则进行处理) 5. 将结果传递回内存 (cudaMemcpy2D实现) 重要概念 - pitch 对于内存的存取来说,对准偏移量为2的幂(现在