CUDA实践指南(十八)

简介:

矩阵乘法中的共享内存($C = AA^T$)
先前矩阵乘法的一个变体可以用来说明如何处理对全局存储器的分步访问以及共享存储器组冲突。 这个变体只是使用A的转置来代替B,所以$C = AA^T$。
$C = AA^T$的简单实现在Unoptimized处理对全局内存的跨步访问中显示
未经优化的对全局存储器的分步访问的处理:

__global__ void simpleMultiply(float *a, float *c, int M)
{
    int row = blockIdx.y * blockDim.y + threadIdx.y;
    int col = blockIdx.x * blockDim.x + threadIdx.x;
    float sum = 0.0f;
    for (int i = 0; i < TILE_DIM; i++) {
        sum += a[row*TILE_DIM + i] * a[col*TILE_DIM + i];
    }
    c[row*M + col] = sum;
}

在未优化的对全局存储器的逐行访问的处理中,C的第row,th col元素是通过取A的第th行和第col行的点积获得的。该内核的有效带宽为3.64 GB / s在NVIDIA Tesla M2090上。 这些结果远远低于C = AB内核的相应测量结果。 不同之处在于,对于每个迭代i,在第二项中A的线程如何访问A中的元素[col TILE_DIM + i]。 对于线程变形,col表示A的转置的顺序列,因此col TILE_DIM表示跨度为w的跨步存取,导致大量浪费的带宽。
避免跨越访问的方式是像以前一样使用共享内存,除非在这种情况下,warp会将一行A读入共享内存块的列中,如使用来自全局内存的合并读取的优化处理跨步访问。
使用来自全局内存的合并读取优化处理跨度访问:

__global__ void coalescedMultiply(float *a, float *c, int M)
{
    __shared__ float aTile[TILE_DIM][TILE_DIM],
        transposedTile[TILE_DIM][TILE_DIM];
    int row = blockIdx.y * blockDim.y + threadIdx.y;
    int col = blockIdx.x * blockDim.x + threadIdx.x;
    float sum = 0.0f;
    aTile[threadIdx.y][threadIdx.x] = a[row*TILE_DIM + threadIdx.x];
    transposedTile[threadIdx.x][threadIdx.y] =
        a[(blockIdx.x*blockDim.x + threadIdx.y)*TILE_DIM +
        threadIdx.x];
    __syncthreads();
    for (int i = 0; i < TILE_DIM; i++) {
        sum += aTile[threadIdx.y][i] * transposedTile[i][threadIdx.x];
    }
    c[row*M + col] = sum;
}

使用来自全局内存的合并读取对跨步访问进行优化处理时,使用共享transposeTile来避免点积中第二项中的未合并访问以及前一示例中共享的aTile技术,以避免第一项中的未合并访问。在NVIDIA Tesla M2090上,该内核的有效带宽为27.5 GB / s。这些结果略低于最终内核对于C = AB所获得的结果。造成差异的原因是共享内存组冲突。
for循环中transposedTile中元素的读取没有冲突,因为每个半变形的线程都会读取瓦片的行,从而导致跨单元的单元跨度。但是,从全局内存复制磁贴到共享内存时发生银行冲突。为了使来自全局存储器的加载能够合并,数据从全局存储器中顺序读取。然而,这需要以列的形式写入共享内存,并且由于在共享内存中使用了wxw磁贴(tile),这导致了w个银行的线程之间的跨度 - 每个线程都经历了同一个银行。 (回想一下,对于计算能力为2.0或更高的设备,w选为32)。这些多路银行冲突非常昂贵。简单的补救措施是填充共享内存数组,使其具有额外的列,如下面的代码行所示。

__shared__ float transposedTile[TILE_DIM][TILE_DIM+1]

这种填充消除了冲突,因为现在线程之间的跨度是w + 1个存储体(即对于当前设备是33个),由于用于计算存储体索引的模算术,这相当于单位步长。 此次更改之后,NVIDIA Tesla M2090上的有效带宽为39.2 GB / s,与上一次C = AB内核的结果相当。
表3总结了这些优化的结果。
1

应该将这些结果与表2中的结果进行比较。从这些表中可以看出,合理使用共享内存可以显着提高性能。
本节中的示例说明了使用共享内存的三个原因:

  • 为了能够对全局内存进行合并访问,特别是为了避免大步幅(对于一般矩阵,步幅远远大于32)
  • 消除(或减少)来自全局内存的冗余负载
  • 避免浪费带宽
目录
相关文章
|
Rust 算法 Go
【密码学】一文读懂MurMurHash3
本文应该是MurMurHash算法介绍的最后一篇,来一起看一下最新的MurMurHash算法的具体过程,对于最新的算法来说,整个流程和之前的其实也比较相似,这里从维基百科当中找到了伪代码,也就不贴出来Google官方给出的推荐代码了,先来看一下维基百科给出的伪代码,这里只有32位的伪代码。
3011 0
【密码学】一文读懂MurMurHash3
|
弹性计算 虚拟化 异构计算
2023阿里云GPU服务器租用价格表(包月/按小时/学生价)
2023阿里云GPU服务器租用价格表(包月/按小时/学生价)阿里云GPU服务器租用价格表包括包年包月价格、一个小时收费以及学生GPU服务器租用费用,阿里云GPU计算卡包括NVIDIA V100计算卡、T4计算卡、A10计算卡和A100计算卡,GPU云服务器gn6i可享受3折优惠,阿里云百科分享阿里云GPU服务器租用价格表、GPU一个小时多少钱以及学生GPU服务器收费价格表
1243 0
|
机器学习/深度学习 缓存 芯片
【AI系统】谷歌 TPU v1-脉动阵列
本文详细分析了谷歌TPU v1的架构与设计,重点介绍了其核心组件如DDR3 DRAM、矩阵乘法单元(MXU)、累加器及控制指令单元,特别是MXU中脉动阵列的工作机制。通过对比TPU v1与CPU、GPU在服务器环境中的表现,展示了TPU v1在提升神经网络计算吞吐量方面的显著优势,尤其是在低延迟和高能效方面。
595 3
|
Go API 微服务
当 go-zero 邂逅 chatgpt...
当 go-zero 邂逅 chatgpt...
|
11月前
|
并行计算 API 调度
加速大语言模型推理:NVIDIATensorRT-LLM更新
本次分享由NVIDIA亚太区资深总监李曦鹏主讲,聚焦于加速大语言模型推理的挑战与解决方案。内容涵盖大模型推理优化、性能提升策略及KVCash在用户请求处理中的应用。通过TensorRT-LLM的更新,NVIDIA提供了高性能推理引擎和多种优化技术,如KVCache优化、InflightBatching等,大幅提升了大模型的推理效率。此外,还介绍了与魔搭社区的合作,支持超过50个主流模型的一键部署,显著降低了使用门槛和成本。
575 1
|
存储 人工智能 缓存
官宣开源 阿里云与清华大学共建AI大模型推理项目Mooncake
近日,清华大学和研究组织9#AISoft,联合以阿里云为代表的多家企业和研究机构,正式开源大模型资源池化项目 Mooncake。
|
开发框架 安全 开发者
Docker 是一种容器化技术,支持开发者将应用及其依赖打包成容器,在不同平台运行而无需修改。
Docker 是一种容器化技术,支持开发者将应用及其依赖打包成容器,在不同平台运行而无需修改。本文探讨了 Docker 在多平台应用构建与部署中的作用,包括环境一致性、依赖管理、快速构建等优势,以及部署流程和注意事项,展示了 Docker 如何简化开发与部署过程,提高效率和可移植性。
299 4
|
搜索推荐 Linux Perl
【专栏】Linux 中有趣的命令:`cowsay` 是 Linux 中一个趣味命令,可在终端创造“会说话的牛”效果
【4月更文挑战第28天】`cowsay` 是 Linux 中一个趣味命令,可在终端创造“会说话的牛”效果。基本用法是输入 `cowsay "text"`,展示带有文字的奶牛形象。使用 `-f` 可换不同牛的样式,`-e` 改变文字颜色。还有 `cowthink` 让牛思考,`cowbell` 添加铃铛声。可与其他命令结合,如 `grep` 或 `sed`,增加终端互动性与趣味性。不论新手还是老手,`cowsay` 都能为你的终端带来更多乐趣和个性化。
519 0
|
人工智能 固态存储 调度
【Paper Reading】结合 NanoFlow 研究,优化大语言模型服务效率的探索
本文将深入探讨 NanoFlow 的关键思路和核心技术,分析 NanoFlow 与 阿里云人工智能平台 PAI 在实际工作中应用的潜力。
|
数据处理 Python
Python数据转换:从Pandas到NumPy转换
Python数据转换:从Pandas到NumPy转换
368 0