*5.1 Global Memory Bandwidth

并行程序的执行速度可能因计算硬件的资源限制而有很大差异。虽然管理并行代码和硬件资源约束之间的交互对于在几乎所有并行编程模型中实现高性能很重要,但这是一种实用技能,最好通过为高性能设计的并行编程模型中的实践练习来学习。在本章中,**我们将讨论CUDA设备中的主要资源约束类型,**以及它们如何影响内核执行性能[Ryoo 2008JICUDA C最佳实践]。为了实现他/她的goals,程序员通常必须找到达到高于应用程序初始版本所需性能水平的方法。在不同的应用中,不同的约束可能会占主导地位,并成为限制因素,通常称为瓶颈。**人们通常可以通过将一个资源使用情况交易给另一个资源来显著提高应用程序在特定CUDA设备上的性能。**如果这样缓解的资源约束实际上是应用战略之前的主要约束,并且因此加剧的约束不会对并行执行产生负面影响,那么这种策略就很有效。如果没有这种理解,性能调整将是工作;似是而非的策略可能会也可能不会导致性能提升。除了对这些资源限制的洞察力外,**本章还提供了原则和案例研究,旨在培养对可能导致高性能执行的算法模式类型的直觉。**它还建立了成语和想法,这些成语和想法可能会在您的性能调整过程中带来良好的性能改进。

5.1 GLOBAL MEMORY BANDWIDTH

CUDA内核性能的最重要因素之一是访问全局内存中的数据。CUDA应用程序利用了海量数据并行性。当然,CUDA应用程序倾向于在短时间内处理来自全局内存的大量数据。在第4章“内存和数据局部性”中,我们研究了利用共享内存来减少每个线程块中的线程集合必须从全局内存访问的数据总量的 tile 技术。在本章中,我们将进一步讨论内存合并技术,这些技术可以更有效地将数据从全局内存移动到共享内存和寄存器中内存合并技术通常与分层技术结合使用,以允许CUDA设备通过更有效地利用全局内存带宽来发挥其性能潜力。

“最近的CUDA设备使用片上缓存来存储全局内存数据。此类缓存会自动合并更多内核访问模式,并在一定程度上减少了程序员手动重新排列其访问模式的需要。然而,即使有缓存,在可预见的未来,合并技术将继续对内核执行性能产生重大影响。

CUDA设备的全局存储器是用DRAM实现的。数据位存储在小电容器的DRAM单元中,其中存在或没有少量电荷可以区分0和1。从DRAM电池读取数据需要小电容器使用其微小的电荷驱动通往传感器的高电容线,并设置其检测机制,该机制确定电容器中是否存在足够的电荷,以符合“1”(请参阅“为什么DRAM如此缓慢?”侧边栏)。在现代DRAM芯片中,这个过程需要10纳秒。这与现代计算设备的亚纳秒时钟周期时间形成鲜明对比。由于相对于所需的数据访问速度(每字节的亚纳秒访问)来说,这是一个非常缓慢的过程,现代DRAM使用并行来提高其数据访问速率,通常称为内存访问吞吐量。

为什么DRAMS这么慢?
下图显示了DRAM单元格及其访问内容的路径。解码器是一个电子电路,它使用晶体管驱动连接到数千个电池出口门的线路。线路可能需要很长时间才能充满电或放电到所需的水平。
在这里插入图片描述
一个更艰巨的挑战是细胞将垂直线驱动到感应放大器,并允许感应放大器检测其内容。这是基于电荷共享。闸门释放出细胞中储存的少量电荷。如果电池含量为“1”,则微小的电荷必须将长位线大电容的电势提高到足够高的水平,从而触发感应放大器的检测机制。一个很好的比喻是,有人在长长的走廊的一端拿着一小杯咖啡,让另一个人闻到走廊上传播的香气,以确定咖啡的味道。
人们可以通过在每个单元中使用更大、更强的电容器来加快这个过程。然而,DRAM一直朝着相反的方向发展。每个电池中的电容器的尺寸都稳步缩小,因此随着时间的推移,其强度会降低,因此每个芯片中可以存储更多的位。这就是为什么DRAM的访问延迟没有随着时间的推移而减少。

每次访问DRAM位置时,都会实际访问一系列连续的位置,包括请求的位置。每个DRAM芯片中都提供了许多传感器,它们并行工作。每个人都在这些连续的位置中感知到一点的内容。一旦被传感器检测到,来自所有这些连续位置的数据可以以非常高的速度传输到处理器。访问和交付的这些连续位置被称为DRAM突发。如果应用程序集中使用这些突发的数据,DRAM可以以比访问真正的随机位置序列更高的速率提供数据。

认识到现代DRAM的突发组织,当前的CUDA设备采用一种技术,允许程序员通过将线程的内存访问组织成有利的模式来实现高全局内存访问效率。这种技术利用了warp中的线程在任何given时间点执行相同的指令这一事实。当warp中的所有线程执行负载指令时,硬件会检测它们是否访问连续的全局内存位置。也就是说,当warp中的所有线程访问连续的global内存位置时,可以实现最有利的访问模式。在这种情况下,硬件将所有这些访问合并或合并为对连续DRAM位置的合并访问。例如,对于warp的给定负载指令,如果线程0访问全局内存位置N,线程1位置N+1,线程2位置N+2等,所有这些访问都将被合并,或者在访问DRAM时合并为连续位置的单个请求。这种合并访问允许DRAM以突发方式交付数据。

不同的CUDA设备也可能对N施加对齐要求。例如,在一些CUDA设备中,N需要对齐到16字的边界。也就是说,N的下6位都应该是0位。由于存在二级缓存,最近的CUDA设备已经放宽了这种对齐要求。
请注意,现代CPU在其缓存内存设计中也能识别DRAM突发组织。CPU缓存行通常映射到一个或多个DRAM突发。在它们触摸的每条缓存行中充分利用字节的应用程序往往比随机访问内存位置的应用程序实现更高的性能。本章介绍的技术可以进行调整,以帮助CPU程序实现高性能。

在这里插入图片描述

为了了解如何有效使用合并硬件,我们需要回顾在访问C多维数组元素时如何形成内存地址。回顾第3章,可扩展并行执行(图3.3,复制为图5.1为方便起见)C和CUDA中的多维数组元素根据行主要约定放置在线性寻址内存空间中。术语行大调是指数据放置保留了行结构的事实:一行中的所有相邻元素都被放置在地址空间中的连续位置。在图中5.1,0行的四个元素首先按其在行中的外观顺序放置。然后放置第1行中的元素,然后是第2行的元素,然后是第3行的元素。应该清楚的是,M0.0和M1.0.虽然在二维矩阵中似乎是连续的,但在线性寻址内存中放置了四个位置。

图5.2说明了用于内存合并的有利与不利的CUDA内核2D行主要数组数据访问模式。从图4.7中召回。 在我们的简单矩阵乘法内核中,每个线程访问M数组的一行和N数组的一列。读者在继续之前应查看第4.3节。图5.2(A)说明了M数组的数据访问模式,其中warp中的线程读取相邻的行。也就是说,在迭代0期间,线程在0到第31行的warp读取元素0中。在迭代1期间,这些相同的线程读取0到31行的元素1。任何访问都不会合并。更有利的访问模式如图5.2(B)所示,其中每个线程读取N的一列。在迭代0期间,warp 0中的线程读取0到31列的元素1。所有这些通道都将合并。
在这里插入图片描述
为了理解为什么图5.2(B)中的模式比图5.2(A)中更有利,我们需要更详细地审查如何访问这些矩阵元素。图5.3显示了访问4×4矩阵的有利访问模式的一个小例子。图5.3顶部的箭头。显示内核代码的访问模式。这种访问模式是由图4.3中对N的访问生成的。

N[k*Width + Col]

在这里插入图片描述
在k循环的给定迭代中,所有线程的kWidth值都是相同的。召回Col=blockIdx.xblockDim.x+threadIdx.x。由于blockIndx.x和 blockDim.x 的值对同一块中的所有线程都具有相同的值,因此k*width+Col中唯一在线程块之间变化的部分是threadldx.x。由于相邻线程具有连续的threadldx.x值,因此其访问的元素将具有连续的地址。例如,在图5.3中,假设我们使用的是4x4块,并且warp大小为4。也就是说,对于这个玩具示例,我们只使用1个块来计算整个P矩阵。Width,blockDim.x,blockIdx.x为4、4, 和0的值, 对于块中的所有线程。在迭代0中,k值为0,每个线程用于访问 N 的索引
在这里插入图片描述
也就是说,在这个线程块中,访问N的索引只是threadldx.x的值。T0、T1、T2、T3访问的N元素是NLO]、N[1]、N[2]和N[3]。图5.3的“加载迭代0”框说明了这一点。.这些元素位于全局内存中的连续位置。硬件检测到这些访问是由warp中的线程和全局内存中的连续位置进行的。它将这些访问合并成一个合并的访问。这允许DRAM以高速率提供数据。

在下一次迭代中,k值为1。每个线程用于访问N的索引为:
在这里插入图片描述
T0、T1、T2、T3在此迭代中访问的N个元素是N[5]、N[6]、N[7]和N[8],如图5.3.中的“加载迭代1”框所示。所有这些访问再次合并成一个统一的访问,以提高DRAM带宽利用率。

图5.4显示了未合并的矩阵数据访问模式示例。图顶部的箭头显示,每个线程的内核代码按顺序访问行的元素。图5.4顶部的箭头显示了一个线程的内核代码的访问模式。此访问模式由图4.3中对M的访问生成。
在这里插入图片描述

M[Row*Width+k]

在k循环的给定迭代中,所有线程的kwidth值都是相同的。从图4.3中召回。该Row=blockIdx.yblockDim.y+threadIdx.y。由于 blockIndx.y 和 blockDim.y 的值对同一块中的所有线程具有相同的值,因此 RowWidth+k 中唯一可以在线程块之间变化的部分是threadldx.y。在图5.4中,我们再次假设我们正在使用4×4块,并且 warp 大小为4。块中所有线程的 Width, blockDim.y, blockIdx.y 的值为4、4和0。在迭代 0 中,k值为 0。每个线程用于访问M的索引为:
在这里插入图片描述
也就是说,访问M的索引只是threadldx.x
4的值。T0、T1、T2、T3访问的M元素是M[0]、M[4]、M[8]和M[12]。图5.4.中的“负载迭代0”框说明了这一点。这些元素不在全局内存中的连续位置。硬件不能将这些访问合并到合并访问中。

在下一次迭代中,k值为1。每个线程用于访问M的索引为:
在这里插入图片描述
T0、T1、T2、T3访问的M元素是M[1]、M[5]、M[9]和M[13],如图5.4.中的“加载迭代1”框所示。同样,这些访问不能合并为合并访问。

对于一个现实的矩阵,每个维度中通常有数百甚至数千个元素。相邻线程在每次迭代中访问的M元素可以相隔数百个甚至数千个元素。底部的“加载迭代0”框显示了线程如何访问 0 th迭代中的这些非连续位置。硬件将确定对这些元素的访问彼此相距甚远,不能合并。因此,当内核循环通过一行遍默时,对全局内存的访问效率比内核通过一列的情况要低得多。

如果算法本质上需要内核代码来沿行方向遍复数据,则可以使用共享内存实现内存聚合。这个技术,称为corner turning,如图5.5所示。用于矩阵乘法。每个线程从M读取一行,这是一个无法合并的模式。幸运的是,可以使用tile算法来实现合并。正如我们在第4章“内存和数据位置”中讨论的那样,块的线程可以首先合作地将tile加载到共享内存中。必须注意确保这些tile以凝聚模式加载。一旦数据在共享内存中,它们可以按行或列访问,性能变化要小得多,因为共享存储器本质上是作为高速片上内存实现的,不需要合并来实现高数据访问率。
在这里插入图片描述
我们复制图4.16 这里如图5.6,其中矩阵乘法内核加载矩阵M的两块,N到共享内存。回想一下,在每个阶段(第9-11行)开始时,线程块中的每个线程负责将一个M元素和一个N元素加载到Mds和Nds中。请注意,每个tile都涉及TILE_WIDTHZ线程。线程使用threadldx.y和threadldx.y来确定要加载的元素。
在这里插入图片描述
M元素加载在第9行,其中每个线程的索引计算使用ph来定位tile的左端。线性化索引计算等价于二维数组访问表达式M[Row][ph*TILE_SIZE+tx]。请注意,线程使用的列索引仅在threadIdx方面有所不同。行索引由blockldx.y和threadldx.y(第5行)确定,这意味着具有相同blockIdx.y/threadIdx.y和相邻threadldx.x值的同一线程块中的线程将访问相邻的M元素。也就是说,tile 的每一行由TILE_WIDTH线程加载,这些线程的线程ldx在y维度上相同,在x维度中是连续的。硬件将聚合这些负载。

在N的情况下,行索引 phTILE_SIZE+ty 对所有具有相同 threadldx.y 值的线程具有相同的值。问题是具有相邻 threadIdx.x 值的线程是否访问一行的相邻N个元素。注意每个线程的列索引计算, Col=bxTILE_SIZE+tx(见第6行)。第一项,bx*TILE_SIZE,对于同一块中的所有线程都是相同的。第二个项,tx,只是threadldx.x值。因此,具有相邻threadldx.x值的线程可以连续访问相邻的N个元素。硬件将凝聚这些负载

**在 tile 算法中,对 M 和 N 元素的负载都是合并的。**因此,与简单的矩阵乘法相比,tile 矩阵乘法算法有两个优势。**首先,由于共享内存中数据的重用,内存负载的数量减少了。其次,剩余的内存负载被合并,从而进一步提高DRAM带宽利用率。**这两个改进彼此具有倍增效应,并显著提高了内核的执行速度。在当前一代设备上,平铺内核的运行速度比简单内核快30多倍。

图5.6中的第5、6、9、10行。形成了一个常用的编程模式,用于在tile算法中将矩阵元素加载到共享内存中。我们还想鼓励读者通过第12行和第13行的点积循环来分析数据访问模式。请注意,warp中的线程不会访问Mds的连续位置。这不是问题,因为Mds在共享内存中,不需要合并即可实现高速数据访问。

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

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

相关文章

xss-labs(1-5)

环境准备: 靶场下载:下载仓库 zhangmanhui/xss-labs - Gitee.com 启动phpStudy 搭建将文件解压拉到phpStudy的www目录下就行 最后直接访问:127.0.0.1/xss-labs-master/ 最后再准备一个浏览器的插件用来发送请求:HackBar 插件都配置好了,直接加载到你的浏览器的扩展…

以unity技术开发视角对android权限的讲解

目录 前言 Android权限分类 普通权限 普通权限定义 普通权限有哪些 危险权限 危险权限的定义 危险权限有哪些 动态申请权限实例 申请单个权限实例 第一步:在清单文件中声明权限 第二步:在代码中进行动态申请权限 申请多个权限实例 第一步&am…

【win11 绕过TPM CPU硬件限制安装】

Qt编程指南 VX:hao541022348 ■ 下载iso文件■ 右键文件点击装载出现如下问题■ 绕过TPM CPU硬件限制安装方法■ 虚拟机安装win11 ■ 下载iso文件 选择Windows11 (multi-edition ISO)在选择中文 ■ 右键文件点击装载出现如下问题 ■ 绕过T…

希尔顿花园酒店喜迎入华十周年里程碑

【2024年1月8日,中国,上海】作为希尔顿集团旗下标志性高端精选服务酒店品牌,希尔顿花园酒店于今年正式迎来其在华经营十周年的里程碑。自2014年中国首家希尔顿花园酒店在深圳开业以来,中国市场已经成为希尔顿花园酒店全球增长的重…

C++中的返回值优化(RVO)

一、命名返回值优化(NRVO) 是Visual C2005及之后版本支持的优化。 具体来说,就是一个函数的返回值如果是一个对象。那么,正常的返回语句的执行过程是,把这个对象从当前函数的局部作用域,或者叫当前函数的…

2024第15届电子教育、电子商务、电子管理和电子学习国际会议

第十五届电子教育、电子商务、电子管理和电子学习国际会议(IC4E 2024)将于2024年3月18日-21日在日本福冈举办。本次会议以电子技术为核心,围绕电子教育、电子商务、电子管理以及电子学习等各个方面展开研讨,为相关领域的专家学者们…

【Spring 篇】深入浅出:用Spring注解开发的奇妙之旅

在编程的世界里,Spring框架如同一位慈祥的导师,为我们打开了无尽可能性的大门。而在Spring的广袤领域中,注解是我们最亲密的伙伴之一。本篇博客将深入浅出地介绍使用Spring注解进行开发的奇妙之旅,为你解开注解的神秘面纱。 前奏…

2024年远控软件年度盘点:安全、稳定、功能之选

这目录 前言2024年热门远控软件ToDesk向日葵TeamViewerAnyDeskSplashtopAirDroidChrome Remote DesktopMicrosoft远程桌面RayLinkParallels Access 远程控制软件如何选择?1、功能性2、安全性3、易用性4、稳定性 未来展望与建议结语 前言 随着信息技术不断发展&…

使用命令行方式搭建uni-app + Vue3 + Typescript + Pinia + Vite + Tailwind CSS + uv-ui开发脚手架

使用命令行方式搭建uni-app Vue3 Typescript Pinia Vite Tailwind CSS uv-ui开发脚手架 项目代码以上传至码云,项目地址:https://gitee.com/breezefaith/uniapp-vue3-ts-scaffold 文章目录 使用命令行方式搭建uni-app Vue3 Typescript Pinia V…

移动端对大批量图片加载的优化方法(一)

移动端对大批量图片加载的优化方法(一)iOS 本篇主要从iOS开发中可以使用到的对大批量图片加载的优化方法进行整理。 1.异步加载 将图片加载任务放在后台线程中进行,避免阻塞主线程,这样可以保证应用的响应性和流畅性&#xff1…

视频剪辑方法:智能转码从视频到图片序列,高效转换攻略

在视频编辑和后期处理中,经常要将视频转换为图片序列,以便进行单独编辑或应用。下面一起来看云炫AI智剪如何批量智能转码的方法,高效地将视频转换为图片序列。 视频转为序列图片缩略图效果 视频转为序列图片的效果图,画面清晰&a…

vue3 img图片怎么渲染

在 Vue3 中加载图片&#xff08;img&#xff09;src地址时&#xff0c;出现无法加载问题。网上很多都建议使用 require 加载相对路径&#xff0c;如下&#xff1a; <img :src"require(../assets/img/icon.jpg)"/>但是按照这种方式加载又会报错如下&#xff1a;…

Access、Trunk、Hybrid接口接收发送数据帧标签剥离区分

以太网二层接口类型 Access Trunk Hybrid 总结&#xff1a; VLAN原理最全最详细讲解&#xff01;彻底搞懂VLAN打和摘tag过程

亚马逊鲲鹏自动测评系统:提升店铺流量与销售的利器

在跨境电商领域&#xff0c;提升店铺流量、排名以及销售业绩一直是卖家们关注的焦点。近期&#xff0c;亚马逊鲲鹏自动测评系统的推出备受关注&#xff0c;成为卖家们提升竞争力的得力工具。据真实客户反馈&#xff0c;该系统不仅能够全自动化批量操作&#xff0c;而且内置了防…

.NET学习教程一——.net基础定义+VS常用设置

一、定义 .NET分为.NET平台和.NET框架。 .NET平台&#xff08;厨房&#xff09;.NET FrameWork 框架&#xff08;柴米油盐酱醋茶&#xff09; .NET平台&#xff08;中国移动联通平台&#xff09;.NET FrameWork 框架&#xff08;信号塔&#xff09; .NET平台基于.NET Fra…

记一次JSF异步调用引起的接口可用率降低

前言 本文记录了由于JSF异步调用超时引起的接口可用率降低问题的排查过程&#xff0c;主要介绍了排查思路和JSF异步调用的流程&#xff0c;希望可以帮助大家了解JSF的异步调用原理以及提供一些问题排查思路。本文分析的JSF源码是基于JSF 1,7.5-HOTFIX-T6版本。 起因 问题背景…

含中间直流的三相电力电子变压器PET仿真模型

微❤关注“电气仔推送”获得资料&#xff08;专享优惠&#xff09; 背景&#xff1a; 目前高压电网中应用的绝大多数电力变压器都属于传 统电力变压器&#xff0c;传统变压器的优势在于工艺简单、安全性 较强。但传统变压器本身的弊端也非常突出&#xff0c;占地大、重 量大&…

0108作业

#include "widget.h"Widget::Widget(QWidget *parent): QWidget(parent) {this->setWindowTitle("腾讯会议");this->resize(470,800);//设置界面大小this->setFixedSize(470,800);//锁定界面大小this->setStyleSheet("background-color:w…

FPGA状态机学习

Verilog 是硬件描述语言&#xff0c;硬件电路是并行执行的&#xff0c;当需要按照流程或者步骤来完成某个功能时&#xff0c;代码中通常会使用很多个 if 嵌套语句来实现&#xff0c;这样就增加了代码的复杂度&#xff0c;以及降低了代码的可读性&#xff0c;这个时候就可以使用…