CUDA并行计算系列之常量内存与性能测量

红太狼 2022-12-11 10:29 237阅读 0赞

CUDA学习计划:

  1. 最基本的GPU程序;

  2. GPU硬件组成和软件概念;

  3. 共享内存的使用;

  4. 常量内存与性能测量;

  5. GPU程序调试;

  6. 提高CUDA程序运行效率的方法。

1. 常量内存的概念

常量内存用于保存在核函数执行期间不会发生变化的数据。

由于GPU上包含数百个计算单元,因此主要的计算瓶颈已经不在芯片的数学计算吞吐量,而在于芯片的内存带宽(即数据从存储器到计算核心的传输延迟)。

特性:

  1. 1)常量内存的数据不能修改;
  2. 2)使用\_\_constant\_\_修饰符;

2.定义和使用常量内存

使用__constant__修饰符来定义常量内存变量:

  1. //定义一个结构体
  2. #define INF 2e10f
  3. struct Sphere{
  4. float r,g,b;
  5. float radius;
  6. float x,y,z;
  7. __deice__ float hit(float ox,float oy,float *n)
  8. {
  9. float dx=ox-x;
  10. float dy=oy-y;
  11. if(dx*dx+dy*dy<radius*radius)
  12. {
  13. float dz=sqrtf(radius*radius-dx*dx-dy*dy);
  14. *n=dz/sqrtf(radius*radius);
  15. return dz+z;
  16. }
  17. return -INF;
  18. }
  19. }
  20. //核函数中定义常量内存变量
  21. __constant__ Sphere s[20];

当从主机内存复制到GPU上的常量内存时,使用cudaMemcpyToSymbol()函数,而非cudaMemcpy()。

  1. //CPU中分配内存
  2. Sphere *temp_s=(Sphere*)malloc(sizeof(Sphere)*20);
  3. //初始化操作(该处省略,编程时需补上)
  4. //在GPU中为Sphere数据分配内存
  5. HANDLE_ERROR(cudaMalloc((void**)&s,sizeof(Sphere)*20));
  6. //数据传输到GPU中的常量内存中
  7. HANDLE_ERROR(cudaMemcpyToSymbol(s,temp_s,sizeof(Sphere)*20));
  8. //传输完毕释放临时内存
  9. free(temp_s);

3.常量内存的优势和不足

优势:

  1. 对常量内存的单次读操作可以广播到其他邻近线程,这将节约15此读取操作;(同一半线程束之间)

    1. 所谓的邻近线程设计线程束Warp的概念,32个线程是一个线程束,NVIDIA硬件将把单词内存读取操作广播到每个半线程束(Half-Warp,即16个线程),所以会节约15次读取操作。
  2. 常量内存的数据将缓存起来,因此对相同地址的连续读操作将不会产生额外的内存通信量;(不同半线程束之间)

    1. 硬件会主动把这个常量数据缓存在GPU中,在第一次从常量内存读取某个地址数据后,当其他半线程束请求同一个地址时,将命中缓存。

缺点:

  1. 当所有16个线程读相同的地址时,会极大地提升性能;但当分别读取不同的地址时,实际反而会降低性能;

    1. 如果半线程束的所有16个线程需要访问常量内存中不同的数据,那么这16次不同的读取操作会串行化,从而需要16倍的时间发出请求;而从全局内存中读取,那么请求会同时发出。

4.测量运行性能

  1. //定义事件变量
  2. hipEvent_t start, stop;
  3. float dt_ms = 0.0f;
  4. //创建事件
  5. hipEventCreate(&start);
  6. hipEventCreate(&stop);
  7. //开始记录事件
  8. hipEventRecord(start,NULL);
  9. //运行内容在此
  10. //获取事件运行时间
  11. hipEventRecord(stop,NULL);
  12. hipEventSynchronize(start);
  13. hipEventSynchronize(stop);
  14. hipEventElapsedTime(&dt_ms, start, stop);
  15. printf("Transfer CPU -> GPU, time: %lf ms\n", dt_ms);

发表评论

表情:
评论列表 (有 0 条评论,237人围观)

还没有评论,来说两句吧...

相关阅读

    相关 CUDA 并行计算

    CUDA 并行计算 并行计算可以被定义为同时使用许多计算资源 (核心或计算机) 来执行并发计算,一个大的问题可以被分解成多个小问题,然后在不同的计算资源上并行处理这些小