cs336Lecture 5 and7

lecture5

How is a GPU different from a CPU?

CPUs optimize for a few, fast threads while GPUs optimize for many many threads. (CPU目的是优化少但速度快的线程,GPU是针对大量线程进行优化)

GPU有大量的compute units(ALU),优化的是总体数据的处理量,而CPU优化的是latency(每个线程尽快完成)

每个SM内部有大量的计算单元,然后每个SM都会启动很多的线程。

我们有很大的global memory(A100:80GB):big,slow

还有很多寄存器(上图中的蓝色部分):small,fast
Execution model

所以执行模型的流程如下:

我们有一系列线程块,一个线程块会被调度到一个SM上执行。而每个线程块内部有许多线程,实际执行计算的就是这些线程。
Why thread blocks? Shared memory.

在同一个线程块之内的线程有shared memory(as fast as L1 cache)。

流行处理器(SP)可以并行执行线程。SM有很多控制逻辑,它可以决定执行什么,SP的操作是接受相同的指令,并将其应用于许多不同的数据。

在这个execution model中,有三种层级。

1.Threads:用来执行并行任务。所有的线程会执行相同的指令,但有着不同的输入。

2.Blocks:一个block包含很多个threads。每个block在单独的SM上运行,并拥有独立的共享内存。

3.Warp:线程总是被划分为连续的32个为一组去执行。每一个block被划分为不同的warps。

在GPU内部的memory传输中,每个线程私有一个Registers和local memory。理想情况下,某个线程执行任务所需要的一小块数据,可以写入shared memory,所有线程可以方便共享。相反,如果一个线程需要访问散落的数据,那就不得不写入global memory,会非常慢。

也就是说,跨越block的数据通信必须写入global memory。

这就说明了在做神经网络架构时,我们要尽可能多的执行矩阵乘法运算。

How do we make GPUs go fast?

Triclk1:Control divergence :

GPUs操作在SIMT模型上---每个处于同一个warp的thread执行相同的指令。

假设有以下条件语句:

当执行if语句时,其它四个线程会停止。why?我不能在这些不同的线程上同时执行'A'和'X'吗?答案是每个线程必须执行相同的指令。所以在一个warp内部的条件语句可能非常有破坏性,因为它们会迫使你暂停那些完全没有按照主控制流执行的线程。
Trick2:Low precision computation

通过 ReLU(x)=max(0,x),我们来举个例子,对于 Float 32 来说,Memory access 需要读取一次 x, 1 if x < 0 需要 write 一次,float 32 = 8 bytes。由于需要比较大小所以 Operations 为 1 次,整个 Intensity: 8 bytes / FLOP。对于 Float 16 来说,float 16 = 4 bytes,但是 Operations 不变,所以 Intensity 整整小一倍。
Trick3:Operator fusion

将GPU看作一个工厂,输入来自于一个房子(内存),工厂接收小方块,计算后输出小三角。

如果增加计算能力,但是传送带负责将内存数据传送到计算单元,是有限带宽的,这样的话,我们就无法同时使用两个工厂。也就是说,我们仍然受限于从内存到计算传输数据的速度。

操作融合的思想就是:相比于左图需要不断的将数据运回内存再传输给计算单元,我可以在计算单元中一直运算,直到我必须将其送回内存时。
Trick4:Recomputation

在梯度回流的时候,我们会选择存储 activations,但这样会导致大量的 memory read/write,不如 Throw away the activations, re-compute them!这样我们会牺牲一点计算,来换取更少的内存访问。
Memory coalescing and DRAM(内存合并和 global memory)

当一个 warp 中的所有线程同时执行一个 load instruction,并且它们访问的内存地址落在同一个 burst section 内时,这些内存访问可以被合并为一个 DRAM 请求。(the big one): tiling。
tiling 是对线程进行分组和排序,以尽量减少 global memory access。下面这张图是一个实际的矩阵相乘的例子,这种情况下,thread0,0 和 thread0,1 要从 global memory 读取两次 M0,0,这显然会降低速度。那我们应该怎么办呢,将矩阵分割为很多的 tiles,然后加载进 shared memory。这样计算的优点在于:重复读取使用 shared memory 而非 global memory,速度快;线程访问的内存地址更连续,符合内存合并的优化原则,提高效率。

Lecture7

相关推荐
从琳开始98914 分钟前
从Socket到TCP回显服务器:Java网络编程完整指南
java·服务器·网络·tcp/ip·java-ee
养军博客14 分钟前
Spring Security 4.x / 5.x / 6.x 配置全对比:前后端不分离与前后端分离
java·后端·spring·springsecurity
wifi___15 分钟前
SpringBoot自动装配原理
java·spring boot·后端
zrc00700732 分钟前
steam无法登录 steam错误 登录时出现错误。请稍后再试。解决办法 steam无法登录解决办法 湖南地区steam DNS问题解决办法
windows·经验分享·游戏·缓存·游戏程序·创业创新·玩游戏
SL_staff44 分钟前
制造订单交付闭环实践:用跨部门计划模板解决缺料-停机-返工三角死循环
java·开源·产品
device_Any1 小时前
接口文档写着三个字段,接口返回了五个
android·java·linux
CCblandy1 小时前
缓存淘汰实测:一次全表扫描把 LRU 命中率从 46% 打到 38%,W-TinyLFU 守住 50% 却贵 11 倍
后端·python·缓存·性能优化·架构
Wang's Blog1 小时前
Java 项目实战: 交友项目 - 小视频模块实战:访客记录、FastDFS 存储与 SpringCache 缓存
java·缓存·交友
香蕉大香蕉(06敬畏市场)1 小时前
MySQL 单点详解(09)
java·数据库·mysql·面试·八股·大厂实习
吹什么轩2 小时前
constexpr 完全指南:从 const 的两种含义,到编译期计算的四次演进
java·前端·javascript