4.7 MEMORY AS A LIMITING FACTOR TO PARALLELISM

虽然CUDA寄存器和共享内存在减少对全局内存的访问次数方面非常有效,但必须注意保持在这些内存的容量范围内。这些内存是线程执行所需的资源形式。每个CUDA设备提供有限的资源,从而限制了给定应用程序可以同时驻留在SM中的线程数量。通常,每个线程需要的资源越多,每个SM中可以驻留的线程就越少,同样,在整个设备中并行运行的线程也就越少。

为了说明内核的寄存器使用与设备可以支持的并行性水平之间的交互,假设在当前一代设备D中,每个SM可以容纳多达1536个线程和16,384个寄存器。虽然16,384是一个大数字,但考虑到每个SM中可以驻留的线程数量,每个线程只允许使用非常有限的寄存器。为了支持1536个线程,每个线程只能使用16,384/1536 = 10个寄存器。如果每个线程使用11个寄存器,则可以在每个SM中同时执行的线程数量将减少。这种减少发生在块粒度上;例如,如果每个块包含512个线程,则通过一次减少512个线程来实现线程的减少。因此,从1536开始,下一个较小的线程数量将是1024,这表明可以同时驻留在每个SM中的线程减少1/3。该程序可以大幅减少可用于调度的warp数量,从而降低处理器在存在长延迟操作的情况下找到有用工作的能力。

每个SM可用的寄存器数量因设备而异。应用程序可以动态确定所用设备的每个SM中可用的寄存器数量,并选择使用适合该设备的寄存器数量的内核版本。寄存器的数量可以通过调用cudaGetDeviceProperties函数来确定,该函数在第3.6节中进行了讨论。假设变量&dev_prop传递给设备属性的函数,字段dev_prop.regsPerBlock生成每个SM中可用的寄存器数量。对于设备D,此字段的返回值应为16,384。然后,应用程序可以将这个数字除以驻留在每个SM中的目标线程数,以确定可以在kerel中使用的寄存器数量。

共享内存使用也可以限制分配给每个SM的线程数量。我们可以假设同一设备D有16,384(16K)字节的共享内存,在每个SM中分配给线程块。我们也可以假设D中的每个SM最多可容纳8个block。要达到这个最大值,每个块不得使用超过2K字节的共享内存;否则,每个SM中可以驻留的块数量将减少,使这些块使用的共享内存总量不超过10K字节。例如,如果每个块使用5K字节的共享内存,则每个SM的分配不能超过三个块。

对于矩阵乘法示例,共享内存可以成为限制因素。对于16×16的tile尺寸,每个块需要16×16×4=1K字节的存储Mds。(请注意,每个元素都是foat类型,为4字节。)Nds还需要1KB。因此,每个块使用2K字节的共享内存。16K字节的共享内存允许8个块同时驻留在SM中。由于这与线程硬件允许的最大值相同,共享内存不是此tile大小的限制因素。在这种情况下,真正的限制是线程硬件限制,每个SM只允许1536个线程。此约束将每个SM中的块数限制为六个。因此,将仅使用6*2KB=12KB的共享内存。这些限制从一个设备到另一个设备,但可以在运行时通过设备查询确定。

每个SM中共享内存的大小也可能因设备而异。每一代或型号的设备在每个SM中可以有不同数量的共享内存。内核通常希望能够根据硬件中的可用量使用不同数量的共享内存。我们可能想要一个主机代码来动态确定共享内存的大小,并调整内核使用的共享内存量,这可以通过调用cuda-GetDeviceProperties函数来完成。我们假设变量&dev_prop传递给函数,而字段dev_prop.sharedMemPerBlock gqives每个SM中可用的寄存器数量。然后,程序员可以确定每个块应该使用的共享内存量。

不幸的是,图4.16中的内核不支持这一点。图4.16 中使用的声明。将其共享内存使用大小硬连接到编译时常数:

__shared__ float Mds[TILE_WIDTH][TILE_WIDTH];
__shared__ float Nds[TILE_WIDTH][TILE_WIDTH];

也就是说,Mds和Nds的大小设置为TILE_WIDTH2元素,无论编译时TILE_WIDTH的值如何。为了说明,假设该文件包含

#define TILE_WIDTH 16.

Mds和Nds都将有256个元素。如果我们想更改Mds和Nds的大小,我们更改TILE_WIDTH的值并重新编译代码。如果不重新编译,内核无法在运行时轻松调整其共享内存使用情况。

我们可以在CUDA中通过不同风格的声明来启用这种调整。我们可以在共享内存声明前面添加一个“C extern”关键字,并在声明中省略数组的大小。以这种方式,Mds和Nds的声明读作

extern __shared__ Mds[];
extern __shared__ Nds[];

请注意,数组现在是一维的。我们需要使用基于垂直和水平索引的线性索引。

当我们启动内核时,我们可以根据设备查询结果动态确定要使用的共享内存量,并将其作为第三个配置参数提供给内核启动。修订后的内核可以通过以下语句启动:
在这里插入图片描述
其中size_tis是用于声明变量的内置类型,用于保存动态分配数据结构的大小信息。大小以字节表示。在我们的矩阵乘法示例中, 16 × 16 tile,我们的大小为16 × 16 x 4=1024字节。省略了在运行时设置大小值的计算细节。

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

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

相关文章

setup 语法糖

只有vue3.2以上版本可以使用 优点: 更少的样板内容,更简洁的代码 能够使用纯 Typescript 声明props 和抛出事件 更好的运行时性能 更好的IDE类型推断性能 在sciprt标识上加上setup 顶层绑定都可以使用 不需要return ,可以直接使用 使用组件…

快速学习SpringBoot

SpringBoot springboot传统方式构建spring应用程序使用springboot子项目构建起步依赖自动配置其它特性 SpringBoot项目部署Spring项目部署属性配置方式命令行参数方式配置环境变量方式外部配置文件方式 多环境开发-Pofiles多环境开发分组 springboot 传统方式构建spring应用程…

Unity中URP下开启和使用深度图

文章目录 前言一、在Unity中打开URP下的深度图二、在Shader中开启深度图1、使用不透明渲染队列才可以使用深度图2、半透明渲染队列深度图就会关闭 三、URP深度图 和 BRP深度图的区别四、在Shader中,使用深度图1、定义纹理和采样器2、在片元着色器对深度图采样并且输…

【Gin实战教程】快速入门

Gin是一个轻量级的Web框架,使用Go语言开发。它具有高性能、易用性和灵活性的特点,是构建可扩展的Web应用程序的理想选择。 首先,Gin是一个高性能的框架。它基于Go语言的原生HTTP包进行开发,利用了Go语言的并发特性和协程模型&…

WPF自定义漂亮顶部工具栏 WPF自定义精致最大化关闭工具栏 wpf导航栏自定义 WPF快速开发工具栏

在WPF应用程序开发中,自定义一个漂亮的顶部工具栏具有多重关键作用,它不仅增强了用户体验,还提升了整体应用的专业性和易用性。以下是对这一功能的详细介绍: 首先,自定义顶部工具栏是用户界面设计的重要组成部分&…

C++和Java中的随机函数你玩明白了吗?内附LeetCode470.rand7()爆改rand10()巨详细题解,带你打败LeetCode%99选手

文章目录 🚀前言🚀C中的随机函数✈️介绍✈️使用✈️用C的暴力求解✈️用C的优化解法 🚀Java中的Math.random()函数 🚀前言 大家好啊!阿辉在刷题时遇到一个很有意思的题LeetCode470.用rand7()实现rand10()&#xff0…

应对 DevOps 中的技术债务:创新与稳定性的微妙平衡

技术性债务在DevOps到底意味着什么?从本质上讲,这是小的开发缺陷的积累,需要不断地返工。它可能由多种原因引起,例如快速交付新功能的压力,这可能会导致团队不得不牺牲代码的整洁和完善。但这些不完整的小代码&#xf…

5.3 WARPS AND SIMD HARDWARE

我们现在把注意力转向线程执行中可能限制性能的方面。回想一下,启动CUDA内核会生成一个线程网格,该网格被组织为两级层次结构。在顶层,网格由一维、二维或三维块阵列组成。在底层,每个块依次由一维、二维或三维线程阵列组成。在第…

从0开始python学习-45.pytest框之将所有的用例封装到一个类中,实现极限封装,并测试用例校验

目录 1. 封装一个用于校验yaml测试用例参数的方法:model_util.py 2. 校验方法是否正确 3. 封装一个方法,用于读取所有的用例:test_all_case.py 1. 封装一个用于校验yaml测试用例参数的方法:model_util.py from dataclasses imp…

Ant Design 日期选择器 a-date-picker 的使用

代码如下&#xff1a; data() {return {initializationTime: } },<a-form-item label"上映时间" :labelCol"labelCol" :wrapperCol"wrapperCol"><a-date-pickerv-model"initializationTime"format"YYYY-MM-DD HH:mm:ss&…

物理实验2023年下B卷部分题目总结

物理实验考试每个实验的题目由5个题变成8个题了QAQ 交直流电桥 1.惠斯通电桥不适于阻值较低&#xff08;1欧以下&#xff09;电阻的原因 2.立式电桥与卧式电桥的比较&#xff08;灵敏度、准确度、测量范围&#xff09; 3.交流电桥平衡法测电容的电路接线 4.铜热电阻、热敏…

Redis基本原理和基础知识

目录 一、基本原理 &#xff08;一&#xff09;非关系型数据库 &#xff08;二&#xff09;关系型数据库与非关系型数据库的区别 &#xff08;三&#xff09;Redis简介 1.什么是Redis 2.数据存储结构 3.默认端口号 4.数据类型 &#xff08;1&#xff09;五大基础类型 …

Linux文件系统与日志服务管理

目录 一.Linux文件系统 1.inode表和block &#xff08;1&#xff09;inode &#xff08;2&#xff09;block 2.查看inode号命令 3.Linux系统文件三种主要时间属性 4.磁盘空间还剩余很多但无法继续创建文件 5.inode大小 二.日志 1.日志保存位置 2.日志文件的分类 &a…

Linux ls命令

目录 一. 配置项1.1 ls -l1.2 ls -a1.3 ls -lrt1.4 ls -ld .?* 二. 案例2.1 查看指定文件夹下文件的数量2.2 查看多个文件夹下文件信息 一. 配置项 1.1 ls -l ⏹ ls 列出当前文件夹下所有文件名称(不包含隐藏文件) jmw_num_00 jmw_num_02 jmw_num_04 jmw_num_06 jmw_n…

手机怎么把卷子的答案擦掉?4款神器帮你轻松搞定

手机怎么把卷子的答案擦掉&#xff1f;随着技术的不断进步&#xff0c;手机已经成为我们日常生活中不可或缺的一部分。除了通信和娱乐功能之外&#xff0c;手机还可以在学习和考试方面发挥重要作用。比如&#xff0c;手机可以帮助学生们进行考试前的复习和准备。学生们还可以将…

Qt 三维柱状图 Q3DBar 和 三维条形图中的数据序列 QBar3DSeries

(一) 使用 Q3DBars 图形类和 QBar3DSeries 序列类可以绘制三维柱状图 窗口右侧是用 Q3DBars 和 QBar3DSeries 绘制的三维柱状图&#xff0c;这个图只有一个QBar3DSeries序列&#xff0c;数据是按行存储的&#xff0c;可以有多行。水平方向是行坐标轴和列坐标轴&#xff0c;使用…

食品饮料加工厂需要哪些污水处理设备和工艺

食品饮料加工厂是一类特殊的工业领域&#xff0c;其生产过程中产生的污水具有较高的含有机物质浓度和COD&#xff08;化学需氧量&#xff09;指标&#xff0c;因此需要根据自身的实际情况选择合适的污水处理设备和工艺。以下是食品饮料加工厂常见的污水处理设备和工艺&#xff…

C#不会循环响应的Action设计与实现

目录 一、简述二、测试代码三、测试的输出四、核心代码五、其它 一、简述 特点&#xff1a; 不光是能防止直接的死循环调用&#xff1b;还能防止间接的死循环调用&#xff1b;还支持对不同参数判定&#xff0c;不同参数的调用可以不当循环调用&#xff1b; 消息事件系统中必…

element-ui确认框

代码示例&#xff1a; <template slot-scope"scope"><el-popconfirmtitle"确定删除吗&#xff1f;"confirm"doDelete"><el-button type"danger" slot"reference" click"del(scope.row.id)">删…

转速传感器信号正弦波方波锯齿波信号输入隔离转换器200mV~50V/5V/12V/24V转0-5V/0-12V/0-24V/集电极开路输出

特点 转速传感器信号直接输入&#xff0c;方波信号输出正弦波、锯齿波信号输入&#xff0c;方波信号输出200mV峰值微弱信号的放大与整形不改变原波形频率&#xff0c;响应速度快电源、信号&#xff1a;输入/输出 3000VDC三隔离辅助电源&#xff1a;5V、12V、15V或24V直流单电源…