当前位置: 首页 > news >正文

优达学城-并行编程-Unit2 硬件内存

GPU负责给SM分配wrap,SM以并行方式运行程序

在一个SM上跑的所有线程可能合作解决一个子问题(错的,不一定的)

一个单Kernel程序在多个wrap上运行,包含X线程块和Y线程块,可以确定x y先后跑的顺序或是在哪个SM上跑吗?

答:伐晓得(这是cuda的小秘密= =||)

GPU的优越性:

1.快速切换SM运行,无法知其间通信

2.可扩展性强,GPU越大,任务分散越广

CUDA存储器类型:

每个线程拥有自己的register and loacal memory;

每个线程块拥有一块shared memory;

所有线程都可以访问global memory;

还有,可以被所有线程访问的只读存储器:constant memory and texture memory

1、  寄存器Register

  寄存器是GPU上的高速缓存器,其基本单元是寄存器文件,每个寄存器文件大小为32bit.

  Kernel中的局部(简单类型)变量第一选择是被分配到Register中。

  特点:每个线程私有,速度快。

2、  局部存储器 local memory

  当register耗尽时,数据将被存储到local memory。如果每个线程中使用了过多的寄存器,或声明了大型结构体或数组,或编译器无法确定数组大小,线程的私有数据就会被分配到local  memory中。

  特点:每个线程私有;没有缓存,慢。

  注:在声明局部变量时,尽量使变量可以分配到register。如:

  unsigned int mt[3];

  改为:unsigned int mt0, mt1, mt2;

3、  共享存储器 shared memory

  可以被同一block中的所有线程读写

  特点:block中的线程共有;访问共享存储器几乎与register一样快.

[cpp]  view plain  copy
 
  1. //u(i)= u(i)^2 + u(i-1)  
  2. //Static  
  3. __global__ example(float* u) {  
  4.     int i=threadIdx.x;  
  5.     __shared__ int tmp[4];  
  6.      tmp[i]=u[i];  
  7.      u[i]=tmp[i]*tmp[i]+tmp[3-i];  
  8. }  
  9.   
  10. int main() {  
  11.     float hostU[4] = {1, 2, 3, 4};  
  12.     float* devU;  
  13.     size_t size = sizeof(float)*4;  
  14.     cudaMalloc(&devU, size);  
  15.     cudaMemcpy(devU, hostU, size,  
  16.     cudaMemcpyHostToDevice);  
  17.     example<<<1,4>>>(devU, devV);  
  18.     cudaMemcpy(hostU, devU, size,  
  19.     cudaMemcpyDeviceToHost);  
  20.     cudaFree(devU);  
  21.     return 0;  
  22. }  
  23.   
  24. //Dynamic  
  25. extern __shared__ int tmp[];  
  26.   
  27. __global__ example(float* u) {  
  28.     int i=threadIdx.x;  
  29.      tmp[i]=u[i];  
  30.      u[i]=tmp[i]*tmp[i]+tmp[3-i];  
  31. }  
  32.   
  33. int main() {  
  34.     float hostU[4] = {1, 2, 3, 4};  
  35.     float* devU;  
  36.     size_t size = sizeof(float)*4;  
  37.     cudaMalloc(&devU, size);  
  38.     cudaMemcpy(devU, hostU, size, cudaMemcpyHostToDevice);  
  39.     example<<<1,4,size>>>(devU, devV);  
  40.     cudaMemcpy(hostU, devU, size, cudaMemcpyDeviceToHost);  
  41.     cudaFree(devU);  
  42.     return 0;  
  43. }  
 

 

 4、  全局存储器 global memory

  特点:所有线程都可以访问;没有缓存

[cpp]  view plain  copy
 
  1. //Dynamic  
  2. __global__ add4f(float* u, float* v) {  
  3. int i=threadIdx.x;  
  4.  u[i]+=v[i];  
  5. }  
  6. int main() {  
  7.     float hostU[4] = {1, 2, 3, 4};  
  8.     float hostV[4] = {1, 2, 3, 4};  
  9.     float* devU, devV;  
  10.     size_t size = sizeof(float)*4;  
  11.     cudaMalloc(&devU, size);  
  12.     cudaMalloc(&devV, size);  
  13.     cudaMemcpy(devU, hostU, size,  
  14.     cudaMemcpyHostToDevice);  
  15.     cudaMemcpy(devV, hostV, size,  
  16.     cudaMemcpyHostToDevice);  
  17.     add4f<<<1,4>>>(devU, devV);  
  18.     cudaMemcpy(hostU, devU, size,  
  19.     cudaMemcpyDeviceToHost);  
  20.     cudaFree(devV);  
  21.     cudaFree(devU);  
  22.     return 0;  
  23. }  
  24.   
  25. //static  
  26. __device__ float devU[4];  
  27. __device__ float devV[4];  
  28.   
  29. __global__ addUV() {  
  30. int i=threadIdx.x;  
  31.  devU[i]+=devV[i];  
  32. }  
  33.   
  34. int main() {  
  35.     float hostU[4] = {1, 2, 3, 4};  
  36.     float hostV[4] = {1, 2, 3, 4};  
  37.     size_t size = sizeof(float)*4;  
  38.     cudaMemcpyToSymbol(devU, hostU, size, 0, cudaMemcpyHostToDevice);  
  39.     cudaMemcpyToSymbol(devV, hostV, size, 0, cudaMemcpyHostToDevice);  
  40.      addUV<<<1,4>>>();  
  41.     cudaMemcpyFromSymbol(hostU, devU, size, 0, cudaMemcpyDeviceToHost);  
  42.     return 0;  
  43. }  

 

   5、  常数存储器constant memory

   用于存储访问频繁的只读参数

   特点:只读;有缓存;空间小(64KB)

   注:定义常数存储器时,需要将其定义在所有函数之外,作用于整个文件 

1 __constant__ int devVar;
2 cudaMemcpyToSymbol(devVar, hostVar, sizeof(int), 0, cudaMemcpyHostToDevice)
3 cudaMemcpyFromSymbol(hostVar, devVar, sizeof(int), 0, cudaMemcpyDeviceToHost)

 6、  纹理存储器 texture memory

     是一种只读存储器,其中的数据以一维、二维或者三维数组的形式存储在显存中。在通用计算中,其适合实现图像处理和查找,对大量数据的随机访问和非对齐访问也有良好的加速效果。

     特点:具有纹理缓存,只读。

TNE END

 
1

 

转载于:https://www.cnblogs.com/yangyang0717/p/6699469.html

相关文章:

  • ajax,json
  • 修饰符
  • 网络中数据的传输过程
  • 如何把你的Windows PC变成瘦客户机
  • codevs 1086 栈(Catalan数)
  • Java设计模式---策略模式
  • 2017BUPT校赛 H-Black-white Tree
  • hibernate之复合主键作为外键的相关配置
  • js中match函数方法
  • 51NOD 1237 最大公约数之和 V3 [杜教筛]
  • 20169219 2016-2017-2 《移动平台开发》第七周作业
  • Verilog基础知识0(`define、parameter、localparam三者的区别及举例)
  • redis安装配置
  • U-Mail邮件中继针对性横扫邮件通关六大阻力
  • 博客、文章索引。
  • 自己简单写的 事件订阅机制
  • [nginx文档翻译系列] 控制nginx
  • 《用数据讲故事》作者Cole N. Knaflic:消除一切无效的图表
  • 10个确保微服务与容器安全的最佳实践
  • docker容器内的网络抓包
  • ECMAScript6(0):ES6简明参考手册
  • ES6系统学习----从Apollo Client看解构赋值
  • Spring Security中异常上抛机制及对于转型处理的一些感悟
  • springMvc学习笔记(2)
  • SSH 免密登录
  • Vue 重置组件到初始状态
  • 服务器之间,相同帐号,实现免密钥登录
  • 构建二叉树进行数值数组的去重及优化
  • 那些被忽略的 JavaScript 数组方法细节
  • 驱动程序原理
  • 想写好前端,先练好内功
  • 一道面试题引发的“血案”
  • 译米田引理
  • 原生js练习题---第五课
  • ​ssh免密码登录设置及问题总结
  • # 20155222 2016-2017-2 《Java程序设计》第5周学习总结
  • #【QT 5 调试软件后,发布相关:软件生成exe文件 + 文件打包】
  • #LLM入门|Prompt#1.7_文本拓展_Expanding
  • #我与Java虚拟机的故事#连载13:有这本书就够了
  • (2)Java 简介
  • (6)设计一个TimeMap
  • (function(){})()的分步解析
  • (k8s中)docker netty OOM问题记录
  • (ZT)出版业改革:该死的死,该生的生
  • (分类)KNN算法- 参数调优
  • (附源码)springboot码头作业管理系统 毕业设计 341654
  • (附源码)计算机毕业设计ssm电影分享网站
  • (算法)前K大的和
  • (一)基于IDEA的JAVA基础12
  • (原創) 如何將struct塞進vector? (C/C++) (STL)
  • (原創) 未来三学期想要修的课 (日記)
  • .【机器学习】隐马尔可夫模型(Hidden Markov Model,HMM)
  • .NET 编写一个可以异步等待循环中任何一个部分的 Awaiter
  • .NET面试题(二)
  • .Net中wcf服务生成及调用