CUDA 内存系统

news/2024/4/19 6:20:11/文章来源:https://blog.csdn.net/u011822516/article/details/129227063

CUDA 内存系统

本文主要是针对<cuda c编程权威指南>的总结,由于原书出版的时候cuda刚刚出到cuda6,之后的cuda版本可能有更新,可能需要我翻一翻文档,待更新.

内存系统架构图

在这里插入图片描述

常见的内存作用域与生存期

在这里插入图片描述

在这里插入图片描述

新特性

早期的 Kepler 架构中一个颇为好用的特性就是 CUDA 程序员可以根据应用特点,自行配制 L1 Cache 和 Shared Memory 的大小。在 Volta 架构中,我们又重新引入这个特性,并且将两者的总大小做到了 128 KB。相信这对于有 Transpose,Histogram 需求的应用,或者严重依赖 L1 cache 命中率的应用都会带来不小的提高。

寄存器

寄存器是一个在SM中由活跃线程束划分出的较少资源。在核函数中使用较少的寄存器将使在SM上有更多的常驻线程块。每个SM上并发线程块越多,使用率和性能就越高。

如果一个核函数使用了超过硬件限制数量的寄存器,则会用本地内存替代多占用的寄存器。这种寄存器溢出会给性能带来不利影响。

本地内存

核函数中符合存储在寄存器中但不能进入被该核函数分配的寄存器空间中的变量将溢出到本地内存中。本地内存实际上只是全局内存,他只是一个逻辑上的概念,因此具有和全局内存一样的特性,低带宽.

编译器可能存放到本地内存中的变量有:

  • 在编译时使用未知索引引用的本地数组
  • 可能会占用大量寄存器空间的较大本地结构体或数组
  • 任何不满足核函数寄存器限定条件的变量

共享内存

SM中的一级缓存和共享内存都使用64KB的片上内存,因此性能.所以与本地内存或全局内存相比,它具有更高的带宽和更低的延迟。

可以认为是可编程的缓存.

每一个SM都有一定数量的由线程块分配的共享内存。因此,必须非常小心不要过度使用共享内存,否则将在不经意间限制活跃线程束的数量。

共享内存是线程之间相互通信的基本方式。一个块内的线程通过使用共享内存中的数据可以相互合作。

常量内存(待补充)

目前看到的特点, 在核函数中是只读内存,作用域是全局,针对于全部设备. 同一线程块(本质上是线程束warp)线程内读相同内存地址的数据,性能很好.

常量内存驻留在设备内存中,并在每个SM专用的常量缓存中缓存。常量变量必须在全局空间内和所有核函数之外进行声明。对于所有计算能力的设备,都只可以声明64KB的常量内存。常量内存是静态声明的,并对同一编译单元中的所有核函数可见。核函数只能从常量内存中读取数据。因此,常量内存必须在主机端使用下面的函数来初始化.线程束中的所有线程从相同的内存地址中读取数据时,常量内存表现最好。举个例子,数学公式中的系数就是一个很好的使用常量内存的例子,因为一个线程束中所有的线程使用相同的系数来对不同数据进行相同的计算。如果线程束里每个线程都从不同的地址空间读取数据,并且只读一次,那么常量内存中就不是最佳选择,因为每从一个常量内存中读取一次数据,都会广播给线程束里的所有线程。

纹理内存(待补充)

纹理内存驻留在设备内存中,并在每个SM的只读缓存中缓存。纹理内存是一种通过指定的只读缓存访问的全局内存,是对二维空间局部性的优化,所以使用纹理内存访问二维数据的线程可以达到最优性能。

全局内存

全局内存是GPU中最大、延迟最高并且最常使用的内存。它的声明可以在任何SM设备上被访问到,并且贯穿应用程序的整个生命周期。

一个全局内存变量可以被静态声明或动态声明。在主机上使用cudaMalloc分配使用cudaFee释放.

可以使用缓存来大幅度提高全局内存的性能.

从多个线程访问全局内存时必须注意。因为线程的执行不能跨线程块同步,不同线程块内的多个线程并发地修改全局内存的同一位置可能会出现问题,这将导致一个未定义的程序行为。全局内存常驻于设备内存中,可通过32字节、64字节或128字节的内存事务进行访问。这些内存事务必须自然对齐,也就是说,首地址必须是32字节、64字节或128字节的倍数。优化内存事务对于获得最优性能来说是至关重要的。当一个线程束执行内存加载/存储时,需要满足的传输数量通常取决于以下两个因素:- 跨线程的内存地址分布
- 每个事务内存地址的对齐方式在一般情况下,用来满足内存请求的事务越多,未使用的字节被传输回的可能性就越高,这就造成了数据吞吐率的降低。

固定内存

理论上固定内存不属于gpu的缓存系统,不过既然书里面写了还是放进来.

核心就是在主机端(cpu 控制下的内存),通过避免分页系统,直接使用固定内存来提升从主机传输数据的速率.建议在大规模数据传输的时候使用固定内存,也可以把许多小的传输批处理为更大的传输提高性能.

由于固定内存能被设备直接访问,所以它能用比可分页内存高得多的带宽进行读写。然而,分配过多的固定内存可能会降低主机系统的性能,因为它减少了用于存储虚拟内存数据的可分页内存的数量,其中分页内存对主机系统是可用的。与可分页内存相比,固定内存的分配和释放成本更高,但是它为大规模数据传输提供了更高的传输吞吐量。与可分页内存相比,固定内存的分配和释放成本更高,但是它为大规模数据传输提供了更高的传输吞吐量。。例如,当传输超过10MB的数据时,在Fermi设备上使用固定内存通常是更好的选择。将许多小的传输批处理为一个更大的传输能提高性能,因为它减少
了单位传输消耗。

零拷贝内存

在主机端提供统一的内存访问.集成架构中,CPU和GPU集成在一个芯片上性能较好,在离散架构中则只有优势

在集成架构中,CPU和GPU集成在一个芯片上,并且在物理地址上共享主存。在这种架构中,由于无须在PCIe总线上备份,所以零拷贝内存在性能和可编程性方面可能更佳。对于通过PCIe总线将设备连接到主机的离散系统而言,零拷贝内存只在特殊情况下有优势。因为映射的固定内存在主机和设备之间是共享的,你必须同步内存访问来避免任何潜在的数据冲突,这种数据冲突一般是由多线程异步访问相同的内存而引起的。注意不要过度使用零拷贝内存。由于其延迟较高,从零拷贝内存中读取设备核函数可能很慢。

统一内存寻址

统一内存中创建了一个托管内存池,内存池中已分配的内存空间可以用相同的内存地址在CPU和GPU上访问。底层系统在统一内存空间中自动在主机和设备间进行数据传输,而这种传输对于应用程序而言是透明的,简化了程序代码。

统一内存寻址功能上类似零拷贝内存,但是相比于零拷贝内存他的核函数访问速率更快。同时他提供的函数的返回指针可以同时在核函数和主机代码中使用,因此提高了可读性和维护性.

缓存

GPU缓存
与CPU缓存类似,GPU缓存不可编程,其行为出厂是时已经设定好了。GPU上有4种缓存:

一级缓存(L1)
二级缓存(L2)
只读常量缓存(与常量内存对应)
只读纹理缓存(最初只给纹理内存使用的缓存,但是在3.5算力以上的显卡上也支持给全局缓存替代,优势是相比于一级缓存他的粒度更低,32B)
每个SM都有一个一级缓存,所有SM公用一个二级缓存。一级二级缓存的作用都是被用来存储本地内存和全局内存中的数据,也包括寄存器溢出的部分。CUDA允许我们配置读操作的数据是使用一级缓存和二级缓存,还是只使用二级缓存。
与CPU不同的是,CPU读写过程都有可能被缓存,但是GPU写的过程不被缓存,只有加载会被缓存!
每个SM有一个只读常量缓存,只读纹理缓存,它们用于设备内存中提高来自于各自内存空间内的读取性能。

L1 Data-Cache:SM的私有L1 Cache和SMEM共享片上存储,他们的大小是可以配置的,L1 data cache缓存全局内存读和本地内存的读写,并且是non-corherent。本地内存主要用来寄存器溢出、函数调用和自动变量。当L1 cache 被用来缓存全局内存时是只读的,当被用来缓存本地内存时也是可写的。粒度都是128B

L2 Cache: 它被用来缓存各种类型的memory access,且和宿主机的CPU memory保持一致性。采取写回策略。全局本地内存都可以读写(加载和写入),粒度是32B,粒度更细.

关于L1, L2的更多内容可以参考CUDA之L1、L2总结

关于缓存对于全局内存读写的影响可以参考原书

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_74468.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JVM - G1垃圾收集器深入剖析

​​​​​​​1、G1收集器概述 HotSpot团队一直努力朝着高效收集、减少停顿(STW: Stop The World)的方向努力&#xff0c;也贡献了从串行Serial收集器、到并行收集器Parallerl收集器&#xff0c;再到CMS并发收集器&#xff0c;乃至如今的G1在内的一系列优秀的垃圾收集器。 G…

Spring Cache的基本使用与分析

概述 使用 Spring Cache 可以极大的简化我们对数据的缓存&#xff0c;并且它封装了多种缓存&#xff0c;本文基于 redis 来说明。 基本使用 1、所需依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-…

随想录二刷Day06——链表

文章目录链表6. 删除链表的倒数第 N 个结点7. 链表相交8. 环形链表 II链表 6. 删除链表的倒数第 N 个结点 19. 删除链表的倒数第 N 个结点 思路&#xff1a; 用双指针的方法&#xff0c;fast 和 slow 之间保持距离为 n&#xff0c;只需要遍历一次即可完成删除任务。 为了方便…

使用jenkins实现自动化部署springboot应用

1. 前置准备 这里代码仓库使用gitlab。在介绍如何通过gitlab和jenkins进行自动化部署之前&#xff0c;需要先安装完成gitlab以及jenkins。两种程序的安装方式以及相关配置可以参看以下内容&#xff1a; linux中安装gitlab&#xff1a;linux安装极狐gitlab linux中安装jenki…

EasyRecovery16最新免费版电脑数据恢复软件功能介绍

EasyRecovery是一款支持Windows/Mac平台进行恢复图片的专业工具&#xff0c;尤其是各种流行单反相机RAW格式文件&#xff0c;以及超大型视频文件等&#xff0c;推荐摄影爱好者使用。适用于主流相机、无人机、PC、存储卡、USB 闪存驱动器等&#xff0c;由于删除、损坏或意外格式…

[数据结构]:05-循环队列(链表)(C语言实现)

目录 前言 已完成内容 循环队列实现 01-开发环境 02-文件布局 03-代码 01-主函数 02-头文件 03-QueueCommon.cpp 04-QueueFunction.cpp 结语 前言 此专栏包含408考研数据结构全部内容&#xff0c;除其中使用到C引用外&#xff0c;全为C语言代码。使用C引用主要是为了…

CountDownLatch与CyclicBarrier原理剖析

1.CountDownLatch 1.1 什么是CountDownLatch CountDownLatch是一个同步工具类&#xff0c;用来协调多个线程之间的同步&#xff0c;或者说起到线程之间的通信&#xff08;而不是用作互斥的作用&#xff09;。 CountDownLatch能够使一个线程在等待另外一些线程完成各自工作之…

学习网安需要了解的一些基础知识

P1.基本概念 1.POC/EXP POC(proof of concept)常指一段漏洞验证代码&#xff1b;EXP(exploit)指利用系统漏洞进行攻击的动作 PoC是证明漏洞存在的,而 Exp 是利用这个漏洞进一步进行攻击&#xff0c;先有POC&#xff0c;才有EXP 2.Payload/shellcode payload&#xff0…

学习周报2.26

文章目录前言文献阅读摘要方法结果深度学习Encoder-Decoder&#xff08;编码-解码&#xff09;信息丢失的问题Attention机制总结前言 This week,I read an article about daily streamflow prediction.This study shows the results of an in-depth comparison between two di…

Lambda表达式的本质

一直想写一篇文章&#xff0c;来总结lambda表达式&#xff0c;但是之前感觉总结的不是特别到位&#xff0c;现在看了几篇文章和视频后&#xff0c;感觉对lambda表达式有了比较深刻的认识&#xff0c;现在进行记录总结如下&#xff1a; lambda表达式又叫做匿名函数&#xff0c;…

网络应用之HTTP响应报文

HTTP响应报文学习目标能够知道HTTP响应报文的结构1. HTTP响应报文分析HTTP 响应报文效果图:响应报文说明:--- 响应行/状态行 --- HTTP/1.1 200 OK # HTTP协议版本 状态码 状态描述 --- 响应头 --- Server: Tengine # 服务器名称 Content-Type: text/html; charsetUTF-8 # 内容类…

【教程】Notion笔记多平台设置中文显示

这个笔记软件界面挺好看&#xff0c;惊艳到了。 目录 网页版 桌面端 Windows版 Mac端 安卓端 网页版 直接安装这个插件即可&#xff0c;Chrome/Edge适用&#xff1a;Notion中文版 桌面端 都要去这个github下载语言包&#xff0c;用于替换文件&#xff1a;https://github.c…

xxjob分布式任务调度

前言 在工作中使用到了定时任务,通过查找资料选择了xxjob,以下是xxjob的介绍以及基本的使用. xxjob介绍 XXL-JOB是一个分布式任务调度平台&#xff0c;其核心设计目标是开发迅速、学习简单、轻量级、易扩展。 将调度行为抽象形成“调度中心”公共平台&#xff0c;而平台自身…

OpenCV-Python系列(二)—— 图像处理(灰度图、二值化、边缘检测、高斯模糊、轮廓检测)

一、【灰度图、二值化】 import cv2 img cv2.imread("lz2.png") gray_img cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 灰度图 # 二值化&#xff0c;(127,255)为阈值 retval,bit_img cv2.threshold(gray_img, 127, 255, cv2.THRESH_BINARY) cv2.imshow(photo1,im…

Laravel框架03:DB类操作数据库

Laravel框架03&#xff1a;DB类操作数据库一、概述二、数据表的创建与配置三、增删改操作1. 增加信息2. 修改数据3. 删除数据四、查询操作1. 取出基本数据2. 取出单行数据3. 获取一个字段的值4. 获取多个字段的值5. 排序6. 分页五、执行任意的SQL语句一、概述 按照MVC的架构&a…

【R统计】R语言相关性分析及其可视化

&#x1f482; 个人信息&#xff1a;酷在前行&#x1f44d; 版权: 博文由【酷在前行】原创、需要转载请联系博主&#x1f440; 如果博文对您有帮助&#xff0c;欢迎点赞、关注、收藏 订阅专栏&#x1f516; 本文收录于【R统计】&#xff0c;该专栏主要介绍R语言实现统计分析的…

浅谈QWebChannel、QWebChannelAbstractTransport、QWebSocketServer、QWebSocket用法及之间关系

1.前言在现实业务中&#xff0c;经常遇到这样的需求&#xff1a;一端采用web形式开发的&#xff0c;如&#xff1a;客户端采用html、javascript、nodejs开发&#xff1b;而另一端采用C开发&#xff0c;如&#xff1a;Qt开发的服务端。web页面端需和Qt开发的服务端进行通信、数据…

房屋出租管理系统

1. 铺垫 1.1 项目真实开发的过程 上来要做什么&#xff1f;&#xff1f;&#xff1f;&#xff1f; 有电脑—》配环境&#xff08;JDK、IDEA、MAVEN……&#xff09; 这个项目&#xff1a;房屋管理系统 从什么角度出发&#xff0c;第一步做什么&#xff1f;&#xff1f; 架构 …

IoT项目系统架构案例2

项目背景 1.这个项目是对之前的案例的升级改造参考&#xff1a;IoT项目系统架构案例_iot案例_wxgnolux的博客-CSDN博客2.基于方案1的项目实施过程中碰到的问题,对硬件设备标准化的理念及新的功能需求(如根据天气预报温度调水温,APP界面可操作性优化等)•采用目前IoT主流厂商的架…

vue中render函数的作用和参数(vue2中render函数用法)

render 函数是 Vue2.x 新增的一个函数、主要用来提升节点的性能&#xff0c;它是基于 JavaScript 计算。使用 Render 函数将 Template 里面的节点解析成虚拟的 Dom 。Vue 推荐在绝大多数情况下使用模板来创建 HTML。然而在一些场景中&#xff0c;需要 JavaScript 的完全编程能力…