1. DRAM 带宽

1.1 DRAM 核心阵列结构

  • 每个 DRAM 核心阵列约有 \(16M\) bits
  • 每个 bits 存储在由一个晶体管组成的微小电容器中

  • 超小型(8x2-bit)DRAM 内核阵列

1.2 DRAM 核心阵列速度慢

  • 从核心阵列单元读取数据的过程非常缓慢

    • DDR:Core speed = \(\frac{1}{2}\) interface speed

    • DDR2 / GDDR3:Core speed = \(\frac{1}{4}\) interface speed

    • DDR3 / GDDR4:Core speed = \(\frac{1}{8}\) interface speed

    • \(\cdots\) 之后可能会更糟

1.3 DRAM Bursting

  • 对于 DDR{2,3} SDRAM 内核,时钟频率为接口速度的 \(\frac{1}{N}\):

    • 将同一行的 DRAM bits 一次性加载(\(N × interface\ width\))到内部缓冲区,然后以接口速度分 N 步传输
    • DDR3 / GDDR4:\(buffer\ width = 8X\ interface\ width\)

1.3.1 DRAM Bursting Timing 示例

现代 DRAM 系统设计为始终以 burst 模式访问。burst bytes 被传输到处理器,但在访问非连续位置时会被丢弃。

1.3.2 DRAM Bursting with Banking

  • 多个 DRAM Banks 结构

  • DRAM Bursting with Banking

1.4 GPU 片外内存子系统

  • NVIDIA RTX6000 GPU

    • global memory 峰值带宽 = \(672GB/s\)
  • global memory (GDDR6) 接口 @7GHz
    • \(14\ Gbps\) 针脚速度
    • 对于 GDDR6 32 位接口,我们只能维持约 \(56\ GB/s\) 的速度
    • 我们需要更大的带宽(\(672\ GB/s\)), 因此需要 12 个 memory channels

2. CUDA 中的内存聚合

2.1 DRAM Burst —— 系统视图

  • 每个地址空间被划分为 burst 段

    • 每当访问一个位置时,同一 burst 段中的所有其他位置也会被传送到处理器中
  • 基本示例如图:16-byte 地址空间,4-byte burst 段

    • 实际上,我们至少有 4GB 的地址空间,burst 段大小为 128-byte 或更多

2.2 内存聚合

当一个 warp 中的所有 thread 都执行一个 load 指令时,如果所有被访问的位置都属于同一 burst 段,那么只会发出一个 DRAM 请求,并且访问是完全聚合的。

2.3 非聚合访问

  • 当被访问的位置跨越 burst 段边界时:

    • 聚合失败
    • 发出多个 DRAM 请求
    • 访问未完全聚合
  • 访问和传输的部分 bytes 未被 threads 使用

2.4 如何判断一个访问是否聚合

  • 如果数组访问中的索引形式为
\[A[(expression\ with\ terms\ independent\ of\ threadIdx.x) + threadIdx.x]
\]
  • 线性内存空间中的二维 C 阵列(按地址递增的线性化顺序)

2.4.1 基本矩阵乘法的两种访问模式

i 是 kernel code 内积循环中的循环计数器,A 大小为 \(m\times n\),B 大小为 \(n\times k\)。

\[Col = blockIdx.x * blockDim.x + threadIdx.x
\]
  • B 访问模式是聚合的

  • A 访问模式不是聚合的

2.4.2 加载输入 tiles

让每个 thread 在与其 C 元素相同的相对位置加载一个 A 元素和一个 B 元素。

  • int tx = threadIdx.x
  • int ty = threadIdx.y

访问 tile 0 2D 索引:

  • A[Row][tx]
  • B[ty][Col]

原始访问模式 (Original Access Pattern)

在左上角的 d_M 矩阵和右上角的 d_N 矩阵中,红色线条代表传统的逐元素访问方式。在这种模式下:

  • 每个线程直接从全局内存中获取所需的矩阵元素,并进行计算。
  • 这种访问方式可能导致频繁的全局内存访问,效率较低,因为每次访问都要从全局内存中读取数据。

分块访问模式 (Tiled Access Pattern)

在分块访问模式中:

  • d_Md_N 矩阵被分成多个小块(蓝色区域),每个小块会被加载到共享内存中。
  • 每个线程块只需要将其负责的矩阵 tile 拷贝到共享内存,然后对共享内存中的数据进行计算。
  • 通过将小块 tile 加载到共享内存中,线程可以更快地重复使用共享内存中的数据,从而减少了全局内存的访问频率,提高了整体性能。

CUDA 编程学习 (5)——内存访问性能的更多相关文章

  1. CUDA编程学习笔记1

    CUDA编程模型是一个异构模型,需要CPU和GPU协同工作. host和device host和device是两个重要的概念 host指代CPU及其内存 device指代GPU及其内存 __globa ...

  2. cuda编程学习3——VectorSum

    这个程序是把两个向量相加 add<<<N,1>>>(dev_a,dev_b,dev_c);//<N,1>,第一个参数N代表block的数量,第二个参数1 ...

  3. CUDA编程模型之内存管理

    CUDA编程模型假设系统是由一个主机和一个设备组成的,而且各自拥有独立的内存. 主机:CPU及其内存(主机内存),主机内存中的变量名以h_为前缀,主机代码按照ANSI C标准进行编写 设备:GPU及其 ...

  4. CUDA编程学习相关

    1. CUDA编程之快速入门:https://www.cnblogs.com/skyfsm/p/9673960.html 2. CUDA编程入门极简教程:https://blog.csdn.net/x ...

  5. cuda编程学习2——add

    cudaMalloc()分配的指针有使用限制,设备指针的使用限制总结如下: 1.可以将其传递给在设备上执行的函数 2.可以在设备代码中使用其进行内存的读写操作 3.可以将其传递给在主机上执行的函数 4 ...

  6. cuda编程学习6——点积dot

    __shared__ float cache[threadPerBlock];//声明共享内存缓冲区,__shared__ __syncthreads();//对线程块中的线程进行同步,只有都完成前面 ...

  7. CUDA编程学习(一)

    /****c code****/ #include<stdio.h> int main() { printf("Hello world!\n); ; } /****CUDA co ...

  8. cuda编程学习5——波纹ripple

    /共有DIM×DIM个像素,每个像素对应一个线程dim3 blocks(DIM/16,DIM/16);//2维dim3 threads(16,16);//2维kernel<<<blo ...

  9. cuda编程学习4——Julia

    书上的例子编译会有错误,修改一下行即可. __device__ cuComplex(float a,float b):r(a),i(b){} /* ========================== ...

  10. cuda编程学习1——hello world!

    将c程序最简单的hello world用cuda编写在GPU上执行,以下为代码: #include<iostream>using namespace std;__global__ void ...

随机推荐

  1. Linux命令cURL详解,并实现文件定时上传到ftp服务器的程序

    前言 前段时间群里讨论,想实现某个文件定时上传到服务器要怎么来实现.我记得之前做过 一个项目:为高通的iot模组编写FOTA功能:实现模组可以远程下载升级镜像包,实现版本升级功能.并当时使用的一个超级 ...

  2. CF650D Zip-line

    CF650D Zip-line 大概题面: 给定一个长度为 \(n\) 的序列以及\(m\)个操作,每个操作形如" \(a_i,b_i\) ",表示将序列中第 \(a_i\) 个数 ...

  3. Docker不同宿主机网络打通

    本方式使用docker Swarm集群的方式创建overlay 网络进行打通 背景 因java微服务使用nacos做配置中心,为了解决Nacos服务注册使用Docker容器内网ip问题,使用此方案 前 ...

  4. AD(Active Directory )域的搭建与操作

    AD 域的搭建与操作 一.准备工作 准备好 VM 虚拟机和 Server 的安装包. 二.安装 Server 2022 选择标准且有图形界面的进行安装. 选择自定义安装方式. 为虚拟机 server2 ...

  5. 补: Rest 风格请求处理的的内容补充(1)

    补: Rest 风格请求处理的的内容补充(1) Rest风格请求:注意事项和细节 客户端是PostMan 可以直接发送Put,delete等方式请求,可不设置Filter 如果哟啊SpringBoot ...

  6. 关于高清显示屏下canvas绘制模糊问题探索处理

    一般场景 我们看下,我们在高清显示屏下,实现这样一个内容,里面填充颜色及文字.第一种是用普通div元素的方式绘制,第二种就是用canvas的方式来绘制,示例效果如下: 从图上我们可以看出,普通div的 ...

  7. 『面试题』WEB前端面试专题-Promise相关

    题目一 const promise = new Promise((resolve, reject) => { console.log(1); resolve(); console.log(2); ...

  8. ASP.NET Core C# 反射 & 表达式树 (第四篇)

    前言 上一篇说完了动态创建表达式树, 这篇来说一说解析表达式树. 我之所以会用到是因为最近开始大量使用 trigger 来维护冗余. 但 trigger 本身并不好维护 (EF Core 也不支持), ...

  9. JAVA与.NET DES加密解密

    项目需要在两个系统间采用DES加密,一个系统为JAVA开发的,另外一个.Net开发的 在网上找了很多写法但加密出的数据两个系统都无法匹配, 在做了小修改以后终于可以用了,已经测试过 JAVA版本 im ...

  10. 巅峰对话在线研讨 Q&A:Oracle Database 21c vs openGauss 2.0新特性解读和架构演进

    2021年11月11日,墨天轮<巅峰对话>栏目邀请到了两位数据库领域的巅峰人物:云和恩墨创始人盖国强老师,和来自清华大学计算机与技术系的李国良教授,为大家带来了在线研讨<Oracle ...