将朴素矩阵乘法在共享内存中分块,每个线程只计算结果矩阵中的单个元素

news2024/12/24 3:19:27

kenel的block中的每个线程用于计算共享内存中矩阵Pd中的一个元素Pd_(i,j),每个线程都读取Md的一行和Nd的一列。Pd_(0,0)和Pd_(1,0)两个结果是由两个线程完成的。这里一开始只有Pd被加载进共享内存,Md和Nd还在全局内存中:

                                      

上图是一个4×4的矩阵与4×4的矩阵相乘的过程,其中将使用2×2的块block,即每个block中有四个线程,也就是共享内存中的Pd矩阵分成四个块,每个大小2x2来执行,使得block中每个线程计算Pd中一个元素。

上图显示的是(0,0)块的执行结果,按照矩阵乘法的过程可以看出,得到Pd_(0,0)和Pd_(1,0)两个结果是由两个线程完成的,但是它两都需要访问Md矩阵的第一行的四个值,这就说明Md矩阵的第一行需要被访问两次(这里的前提是分块的第一个块中,当然不同块之间还是会有重复访问的问题);同样的也会访问Nd矩阵的每一行两次(每一列两次?),如果说能够采用某种方法使得线程(0,0)和线程(1,0)之间能够合作,那么Md中的元素只要从全局存储器中加载一次就行了,这样对于全局存储器的访问就减少了一半。这里可以发现矩阵乘法这个例子中全局存储器流量潜在的减少量与使用的块的维度成正比,对于N×N的块来说,全局存储器流量就可以减少N倍,也就是流量只有原来的1/N了。
 

这就是使用线程合作的方式将Md和Nd中的元素加载到共享存储器中,但是共享存储器容量相当小,所以还是得注意,不过可以将矩阵Md和Nd中的元素划分成更小的块,而且块的大小是可以选择的,从而放在共享存储器中。

最简单的就是将共享内存中Md和Nd中分成的块的维度等于kenel的块block的维度:把Md和Nd划分成2x2的块放进共享内存:

通过将Md和Nd两个矩阵也分成2×2的块,然后单独的将不同的块加载到共享存储器中,所以得到的Pd值也被分成几个不同的阶段:

第一阶段,

把Md(0,0),Md(1,0),Md(0,1),Md(1,1),送入Mds(0,0),Mds(1,0),Mds(0,1),Mds(1,1).(行主序)。

把Nd(0,0),Nd(1,0),Nd(0,1),Nd(1,1),送入Nds(0,0),Nds(1,0),Nds(0,1),Nds(1,1).(列主序)。

然后用于计算Pd(0,0),Pd(0,1),Pd(1,0),Pd(1,1)。注意计算过程中的行列主序。

第二阶段,

把Md(2,0),Md(3,0),Md(2,1),Md(3,1),送入Mds(0,0),Mds(1,0),Mds(0,1),Mds(1,1).(行主序)。

把Nd(0,2),Nd(1,2),Nd(0,3),Nd(1,3),送入Nds(0,0),Nds(1,0),Nds(0,1),Nds(1,1).(列主序)

然后用于计算Pd(0,0),Pd(0,1),Pd(1,0),Pd(1,1)。注意计算过程中的行列主序。

在每个阶段中,一个块中所有的线程相互合作将Md和Nd中的块加载到共享存储器中:

上图就是具体的执行过程,时间从左往右,其中Mds和Nds表示在共享存储器中对应的位置,线程T_(0,0)负责在第一阶段中将Md_(0,0)和Nd_(0,0)加载到对应的共享寄存器中,以此类推,在阶段一中当加载了Md和Nd矩阵的对应的第(0,0)块的时候,计算一半的值;然后进行第二阶段加载Md和Nd矩阵的(0,1)的块然后接着计算后一半的值。

一般来说,如果一个输入矩阵的维度是N而且块大小为TILE_WIDTH(就是想要将这个矩阵分成的小块的维度,比如上面4×4的矩阵分成的小块的维度是2),那么点积运算分成N/TILE_WIDTH个阶段。这种将每个阶段中使用输入矩阵元素的一个很小的子集,这种集中访问的行为称为局部性。所以如果一个算法能够具有这种局部性,那么无论是在多核CPU还是GPU中,都可以提高性能。

下面就是实现上面步骤的例子代码:

注意这里要用kenel的线程号bx,tx,by,ty乘以共享内存中矩阵的边长TILE_WIDTH来得到矩阵元素的行、列序号。将kenel,block中的线程与共享内存中需要用线程处理的元素连接起来。

代码解释:第一行和第二行进行声明Mds和Nds为共享存储器变量;第三行和第四行将线程索引和块索引放入自动变量中,所以可以利用寄存器来快速的访问这些变量(在函数中自动的标量变量是会放入寄存器中的,作用域是单个线程,也就是每个线程会有tx,ty,bx,by的私有版本);第五行和第六行创建对应的Pd矩阵的行索引和列索引:

上图就是用来解释第五行和第六行的代码的,如何来进行索引Pd矩阵;第八行中m指明点积执行过程中现在执行第几个阶段,每个阶段用到Md中的一个块元素和Nd中的一个块元素,表示已经执行完Md和Nd中m×TILE_WINDTH对元素了;

第九行和第十行就是通过一个块中的线程协作的方式将Md和Nd中一个块内的数据加载到共享存储器中,因为这里还是将2维矩阵以1维向量存储的方式,所以先跳过前面的Row*Width个,从第(Row+1)行开始计算;第十一行使用栅栏同步函数_syncthreads(),确保同一个块中所有的线程都加载好了Mds和Nds;第十二行和第十三行用来计算第m个阶段上的点积部分;第十四行再次调用栅栏同步函数,用于进入下一次的循环中加载Md和Nd的下一个块,保证当前块中所有的线程都已经使用完Mds和Nds的数据。

        虽然采用寄存器,共享存储器和常数存储器可以有效的减少对全局存储器的访问,但是它们自身也是有容量限制的,如果说每个线程要求的存储单元越多,那么每个SM中可以同时驻留的线程就越少,导致在整个存储器中驻留的线程数也越少。假设(G80中)一个SM中寄存器大小为8KB,而且最多能够容纳768个线程,那么每个线程可使用的寄存器个数为8KB/768 = 10.如果每个线程使用11个寄存器,那么线程数目势必要减少,而且是以块的形式来减少的,如果当前块中执行的有256个线程,那么算下来每个SM中可同时驻留的线程数就减少256个,只有512个,使得大大减少线程调度是可用的warp的数量(个人:这里的SM中可以最大驻留768个线程,而一个SM中的寄存器是放在一起的不是单独线程分开的,然后你在kernel函数中指定了块的维度,也就是一个块中有256个线程,那么方便调度就从768减去256,如果寄存器还是不够用那么接着在减少256个线程,这样就使得在kernel中分配的块能够放在一个SM中运行);同样的共享存储器也是个问题,假设(G80)每个SM中共享存储器的大小为16KB,而这总的16Kb是以块划分而不是像上面的8KB的寄存器一样以线程划分,如果每个块使用5KB的共享存储器,那么每个SM最多只能分配3个块。在上面的代码例子中,假设对于16×16的块来说,每个块使用16×16×4 = 1KB的存储空间来存放Mds,同理需要1KB空间存放Nds,每个块需要使用2KB的共享存储空间,但是因为线程的硬件限制,每个SM最多容纳768个线程,使得最多只有3个块,那么只能使用共享存储器的6KB的空间,就浪费了10KB的空间了,不过硬件的限制是因显卡的更新换代而不同的,比如GT200中每个SM最大支持1024个线程。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

嵌入式软件测试方法-质量模型

软件测试评估质量的时候用到的很多测试度量项 质量大师朱兰提出了“质量管理三部曲”,来对企业质量进行管理。 第一部曲:质量策划,致力于制定质量目标并规定必要的运行过程、准备相关资源以实现质量目标。 第二部曲:质量控制&am…

【java】【经验】java: 错误: 不支持发行版本 6

前言:配置过maven之后,发现原来的一些项目运行提示java: 错误: 不支持发行版本 6或者java: 错误: 不支持发行版本 5,主要原因:是因为项目使用的Java版本和安装的Java版本不符合 目录 1 设置项目java版本 2 设置模块版本 3 set…

马尔可夫链的性质和例子

马尔可夫链的重要性质以及两个例题如下: 注意: 例5中有几个地方需要注意: (1)为什么 P 11 P 22 p q ( 1 − p ) ( 1 − q ) ,而 P 33 p q ( 1 − p ) P_{11} P_{22} pq (1-p)(1-q),而P…

低代码开发平台:无限潜力,适用于各类应用程序开发!

随着技术的不断进步和市场需求的变化,低代码开发平台成为了构建应用程序的一种热门选择。低代码开发平台通过简化应用程序开发过程,降低了编程门槛,使非技术人员也能够快速构建功能强大的应用程序。不过,低代码开发平台究竟可以开…

[vue-element-admin]下载与安装

一、环境搭建 1 nodejs 源码地址 sudo apt install build-essential # 内含gcc g make等全家桶git clone git://github.com/nodejs/node.git # 下载源码 cd node sudo ./config sudo make && make install # 编译 node -v # 查看是否编译成功二、遇见的问题 问题…

清风数学建模——插值算法

插值法 文章目录 插值法作用定义概念一维插值问题一维插值多项式原理定理 拉格朗日插值法和牛顿插值法埃尔米特插值分段线性插值分段三次埃尔米特插值法代码三次样条插值及其代码例子n维数据的插值(了解) 作用 数模比赛中,常常需要根据已知的…

QT笔记——QT自定义事件

我们有时候想发送自定义事件 1:创建自定义事件,首先我们需要知道它的条件 1:自定义事件需要继承QEvent 2:事件的类型需要在 QEvent::User 和 QEvent::MaxUser 范围之间,在QEvent::User之前 是预留给系统的事件 3&#…

[ubuntu]创建root权限的用户

一、创建新用户 1、创建新用户 sudo useradd -r -m -s /bin/bash 用户名 # -r:建立系统账号 -m:自动建立用户的登入目录 -s:指定用户登入后所使用的shell2、手动为用户设置密码 passwd 用户名 二、为用户增加root权限 1、添加写权限 ch…

适配器模式:将不兼容的接口转换为可兼容的接口

适配器模式:将不兼容的接口转换为可兼容的接口 什么是适配器模式? 适配器模式是一种结构型设计模式,用于将一个类的接口转换为客户端所期望的另一个接口。它允许不兼容的类能够合作,使得原本由于接口不匹配而无法工作的类能够一…

1.Fay-UE5数字人工程导入(UE数字人系统教程)

Fay-UE5数字人工程导入 1、工程下载:xszyou/fay-ue5: 可对接fay数字人的ue5工程 (github.com) 2、ue5下载安装:Unreal Engine 5 3、ue5插件安装 依次安装以下几个插件 4、双击运行工程 5、切换中文 6、检查插件已启用 7、测试运行

一文看懂intel处理器型号

cpu型号命名 cpu 后缀 外形/功能类型/细分市场后缀优化/设计台式机K高性能,未锁频Φ需要独立显卡S特别版T功耗优化生活方式X/XE最高性能,未锁频移动设备(笔记本电脑 2、2 合 1 电脑)HX最高性能,所有 SKU 未锁频HK高性…

Python源码:使用Tkinter写一个诗词答题软件

废话不多,直接上源码 # 导入用到的库 import tkinter from tkinter import * from tkinter.messagebox import * import random# 准备一个诗词题库列表 shici_list [(词苑千载,群芳竞秀,盛开一枝女儿花"说的是哪位历史上的哪位才女&am…

陀螺玩具跨境电商亚马逊CPC认证

陀螺指的是绕一个支点高速转动的刚体。陀螺是中国民间最早的娱乐工具之一.形状上半部分为圆形,下方尖锐。从前多用木头制成,现代多为塑料或铁制。玩时可用绳子缠绕,用力抽绳,使直立旋转。或利用发条的弹力旋转。传统古陀螺大致是木…

移动端自动化测试实战

UI自动化测试的价值 1、提升回归测试的效率 2、可以进行兼容性测试 UI 自动化测试应用场景 • 冒烟测试自动化:提测之前自动断言提测质量,提供准入参考。 • 功能测试自动化:辅助 QA 与测试工程师的快速验证。 • 验收测试自动化&#xf…

大模型AI人才培养研习会,上海、武汉站同期招募!

伴随预训练大语言模型技术引发的产业变革,市场对AI人才需求也同样发生着深刻变化,教育迎来了新的机遇与挑战。由中国自动化学会主办,百度公司联合知名高校承办的大模型AI人才培养研习会,首场将于8月19日在武汉、上海双城同期举办&…

python安装xgboost报错

ERROR: Could not find a version that satisfies the requirement xgboost (from versions: none) ERROR: No matching distribution found for xgboost 解决办法: 换成国内的pip源 pip install xgboost -i http://pypi.doubanio.com/simple/ --trusted-host py …

python3学习--使用pandas 数据透视表分析数据--入门示例

什么是透视表? 透视表是一种可以对数据动态排布并且分类汇总的表格格式,可以以多种方式和视角查看数据特征 Pandas库提供了一个名为pivot_table的函数,它将一个特性的值汇总在一个整洁的二维表中。 使用示例 pivot_table函数说明 pandas.…

没有硬核技术,怎么抓得住元宇宙的风口?

自 2021 年起,Web 3.0 与元宇宙逐步成为全球科技界的热门概念。Web 3.0 是技术发展方向的未来,元宇宙是应用场景和生活方式的未来,二者之间是相辅相成、一体两面的依存关系。科技巨头如 Meta、谷歌、苹果、华为、腾讯、OPPO 等均已在积极布局…

7.3 详解NiN模型--首次使用多层感知机(1x1卷积核)替换掉全连接层的模型

一.前提知识 多层感知机:由一个输入层,一个或多个隐藏层和一个输出层组成。(至少有一个隐藏层,即至少3层) 全连接层:是MLP的一种特殊情况,每个节点都与前一层的所有节点连接,全连接…

stm32项目(6)——基于stm32的人体检测系统

目录 1.功能设计 2.硬件方案 1.单片机选择 2.人体传感器 3.报警模块 3.程序设计 4.课题意义 5.未来发展 1.功能设计 本系统为日常生活而开发的人体感应报警系统,主体通过HC-SR501模块达到感知人体靠近,检测到人体后单片机控制蜂鸣器和LE…