利用共享存储单元优化应用利用共享存储单元进行矩阵转

简介: 利用共享存储单元优化应用利用共享存储单元进行矩阵转

Udacity的CUDA编程课程中介绍了CUDA实现矩阵转置的六种方式,本文介绍其中的一种方式

如果矩阵为N*N的方阵。该方式让每个线程处理一个矩阵元素,总共需要N*N个线程。首先,声明两个常量并配置blocks,threads:

const int N=1024;
const int K=32;
dim3 blocks(N/K,N/K); 
dim3 threads(K,K);

内核函数:

__global__ void 
transpose_parallel_per_element_tiled(float in[], float out[])
{
  // (i,j) locations of the tile corners for input & output matrices:
  int in_corner_i  = blockIdx.x * blockDim.x, in_corner_j  = blockIdx.y * blockDim.y;
  int out_corner_i = in_corner_j, out_corner_j = in_corner_i;
  int x = threadIdx.x, y = threadIdx.y;
  __shared__ float tile[K][K];
  // coalesced read from global mem, TRANSPOSED write into shared mem:
  tile[y][x] = in[(in_corner_i + x) + (in_corner_j + y)*N];
  __syncthreads();
  // read from shared mem, coalesced write to global mem:
  out[(out_corner_i + x) + (out_corner_j + y)*N] = tile[x][y];
}

内核涉及两个输入参数,in代表输入矩阵,out代表in的转置矩阵。为了更好地理解这段代码,我们将矩阵规模缩小并画图展示。假设N=4,K=2。blocks(2,2),threads(2,2)。

如图所示,矩阵被分成了4个区域,每个区域包含2*2=4个数据,分别由4个线程块进行处理。

矩阵左下那个方形区域由block(0,1)处理。该线程块corner(threads(0,0))所处理数据在in矩阵中的坐标为。S区域的其他数据坐标可由[(icj+y)*N+ici+x]得到,x,y是线程索引。blocks,threads的二维索引值x,y分别代表了矩阵的水平方向和竖直方向。

内核声明了一个和数据块大小相同的共享内存tile,用于存储S区域的数据。block读取S区域数据并按原样复制到tile当中,一个线程复制一个数据。随后block将tile中的数据转置,再把经过转置的tile中的数据写入到out矩阵当中区域。根据转置行列互换的性质可知,block(0,1) corner所处理数据在out矩阵中的坐标为(oci=icj,ocj=ici)即(2,0),区域的其他数据索引可由[(ocj+y)*N+oci+x]得到。转置后,in矩阵区域的数据会被block(0,1)转置到out矩阵。tile转置和写入数据到out是由最后一行代码完成的。

该例中,数据读取和写入都利用了全局内存合并访问,这也说明,对于二维矩阵块(x,y),CUDA按x优先顺序处理线程。


出于某种目的,我需要线程块的尺寸为非方形。假设blocks(4,2),threads(1,2)。内核函数__shared__ float tile[K][K];需要修改为__shared__ float tile[2][1]; 这样修改之后,问题在于无法在tile中对数据进行转置。所以我在将数据写入到out的时候,将位置索引[(oci + x) + (ocj + y)*N]转置为(oci + y) + (ocj + x)*N,实现非方矩阵块的矩阵转置。

这段解释不要看了。内核函数中的in_corner_i,in_corner_j分别代表线程块左上角线程(也就是threads(0,0))在矩阵中的x索引(水平方向)和y索引(竖直方向),作为线程块内部线程索引数据的参照点(线程块(0,0)线程所处理数据在矩阵中的位置)。对于block(0,1),in_corner_i=0,in_corner_j=2。转置后,S区域内的元素会被转置到右上方区域S’。所以block(0,1)的功能就是把in矩阵S区域的数据转置并复制到out矩阵S'区域。这就需要block(0,1)找到out矩阵右上方区域的参照点索引。根据转置行列互换的性质,得到out_corner_i(x索引)=in_corner_j=2,out_corner_j(y索引)=in_corner_i=0。x,y变量分别是线程在线程块中的二维索引。

共享内存tile的尺寸和block一样,block读取in数据并按原样复制到tile当中,一个线程复制一个数据。同步后,再把tile中的数据按转置顺序写入到out矩阵当中的对应位置。转置的过程相当于在共享内存中完成,所以线程读取和写入都用[(in_corner_i + x) + (in_corner_j + y)*N]来索引数据。

 

目录
相关文章
|
10月前
|
SQL 关系型数据库 MySQL
深入解析MySQL的EXPLAIN:指标详解与索引优化
MySQL 中的 `EXPLAIN` 语句用于分析和优化 SQL 查询,帮助你了解查询优化器的执行计划。本文详细介绍了 `EXPLAIN` 输出的各项指标,如 `id`、`select_type`、`table`、`type`、`key` 等,并提供了如何利用这些指标优化索引结构和 SQL 语句的具体方法。通过实战案例,展示了如何通过创建合适索引和调整查询语句来提升查询性能。
1899 10
|
10月前
|
存储 人工智能 算法
深度揭秘超长序列生成任务训练技术
阿里自研的TorchAcc训练引擎提出了超长序列训练方案FlashSequence,针对超长文本理解、视频生成等场景。通过2D Context Parallel和Hybrid FSDP混合分布式策略,结合显存、计算和通信优化,实现了百万级别超长序列模型的高效训练。FlashSequence在算力、显存需求及分布式训练方面进行了多项创新,性能提升显著,最大可达48%。该方案大幅降低了企业创新成本,提升了业务应用的可能性。
|
11月前
|
数据采集 自然语言处理 搜索推荐
基于qwen2.5的长文本解析、数据预测与趋势分析、代码生成能力赋能esg报告分析
Qwen2.5是一款强大的生成式预训练语言模型,擅长自然语言理解和生成,支持长文本解析、数据预测、代码生成等复杂任务。Qwen-Long作为其变体,专为长上下文场景优化,适用于大型文档处理、知识图谱构建等。Qwen2.5在ESG报告解析、多Agent协作、数学模型生成等方面表现出色,提供灵活且高效的解决方案。
1025 49
|
8月前
|
人工智能 安全 Anolis
打造更 AI 的操作系统 《龙蜥+超级探访》第三期走进浪潮信息
且看龙蜥社区如何联合浪潮信息向更高层次的操作系统智能化迈进?
打造更 AI 的操作系统 《龙蜥+超级探访》第三期走进浪潮信息
|
Linux Android开发 C语言
不写一行代码(一):实现安卓基于GPIO的LED设备驱动
本文通过实践操作,展示了在Android系统中不编写任何代码,利用设备树(DTS)配置和内核支持的通用GPIO LED驱动来控制LED设备,并进一步通过C语言编写NDK测试APP来实现LED的闪烁效果。
597 0
不写一行代码(一):实现安卓基于GPIO的LED设备驱动
|
10月前
|
监控 Java API
探索Java NIO:究竟在哪些领域能大显身手?揭秘原理、应用场景与官方示例代码
Java NIO(New IO)自Java SE 1.4引入,提供比传统IO更高效、灵活的操作,支持非阻塞IO和选择器特性,适用于高并发、高吞吐量场景。NIO的核心概念包括通道(Channel)、缓冲区(Buffer)和选择器(Selector),能实现多路复用和异步操作。其应用场景涵盖网络通信、文件操作、进程间通信及数据库操作等。NIO的优势在于提高并发性和性能,简化编程;但学习成本较高,且与传统IO存在不兼容性。尽管如此,NIO在构建高性能框架如Netty、Mina和Jetty中仍广泛应用。
248 3
|
12月前
|
缓存 监控 Java
大厂性能优化的10大顶级方案 (万字图文史上最全)
本文详细介绍了大厂性能优化的10大顶奢方案,涵盖代码优化、缓存优化、异步优化、多线程优化、前端优化、微服务架构优化、硬件升级、数据库优化、过载保护优化以及度量与监控系统等方面。每部分不仅提供了理论知识,还结合实际案例和代码示例,帮助读者全面理解和应用这些优化策略。文章还特别强调了架构设计的重要性,指出架构师需要具备多方面的知识和技能,包括硬件、软件、网络协议、分布式知识等,以应对复杂的技术挑战。最后,作者尼恩分享了自己多年的经验,提供了丰富的技术资源和实战指导,助力读者在面试和工作中取得成功。
大厂性能优化的10大顶级方案 (万字图文史上最全)
|
11月前
|
Ubuntu
Ubuntu禁止内核自动更新
通过上述步骤,您可以在Ubuntu系统中有效地禁用内核的自动更新。这些步骤包括锁定内核版本、禁用自动更新配置、移除不需要的内核包以及禁用相关的自动更新服务。这样可以确保系统在内核层面保持稳定,避免因内核自动更新导致的不必要问题。
2437 1
SublimeText配置Markdown编辑及预览
本文详细介绍了如何配置Sublime Text及相关插件,使之成为Markdown编辑器并且能够在浏览器中实现预览功能。
|
SQL 关系型数据库 MySQL
【MySQL】事务管理 -- 详解(上)
【MySQL】事务管理 -- 详解(上)