GPU选购指南:训练ML模型,我必须买RTX3080吗?( 二 )


“为什么 GPU 适合深度学习”: https://timdettmers.com/Why-are-GPUs-well-suited-to-deep-learning?top_ans=21379913
这是一个高阶解释,很好地说明了为什么 GPU 比 CPU 更适合深度学习 。如果我们关注细节,就能理解是什么让一个 GPU 比另一个更好 。
与处理速度相关的最重要的 GPU 参数本节可以帮助你更直观地理解如何考虑深度学习的性能 。这种理解可以帮助你评估未来的 GPU 。
张量核要点:
  • 张量核将乘法和加法运算所需的 cycle 减少为 1/16——在我举的例子中,对于一个 32×32 的矩阵,从 128 个 cycle 减少到 8 个 cycle 。
  • 张量核减少了反复共享内存访问的次数,从而节省了额外的内存访问 cycle 。
  • 张量核速度如此之快,计算不再是瓶颈 。唯一的瓶颈是如何将数据传输到张量核中 。
现在 GPU 已经足够便宜,几乎每个人都能负担得起一个有张量核的 GPU 。这就是为什么我只推荐具有张量核的 GPU 。了解它们是如何工作的,有助于理解这些专门用于矩阵乘法的计算单元的重要性 。这里我将向你展示一个简单的例子:A*B=C 矩阵乘法,其中,所有矩阵的大小都是 32×32,我们将分别看下,计算模式在有和没有张量核时是什么样的 。
要完全理解这一点,就必须理解 cycle 的概念 。如果一个处理器以 1GHz 的速度运行,它每秒可以完成 10^9 个 cycle 。每个 cycle 都代表一次计算机会 。然而,大多数时候,操作所花费的时间会超过一个 cycle 。因此,它创建了一个管道,用于启动一个操作,它需要等待前一个操作完成所需的 cycle 数 。这也称为操作延迟 。
下面是一些重要操作的延迟:
  • 全局内存访问(最高 48GB):~200 cycle
  • 共享内存访问(每个串流多处理器最高达 164KB):~20 cycle
  • 融合乘加(FFMA):4 cycle
  • 张量核矩阵乘法:1 cycle
此外,你应该知道 GPU 上的最小线程单元是一个包含 32 个线程的包——这被称为 warp 。通常,warp 以同步模式运行——warp 内的线程必须彼此等待 。GPU 上的所有内存操作都针对 warp 进行了优化 。例如,从全局内存中加载的粒度为 32*4 字节,恰好有 32 个浮点数,恰好每个线程一个浮点数 。在串流多处理器(SM,相当于一个 CPU 内核)中,我们最多可以有 32 个 warp=1024 个线程 。SM 的资源被分配给所有活动的 warp 。所以,有时我们想要运行较少的 warp,这样每个 warp 就有更多的寄存器 / 共享内存 / 张量核资源 。
对于下面的两个例子,我们假设计算资源相同 。对于这个 32×32 矩阵乘法的小例子,我们使用 8 个 SM(约为 RTX 3090 的 10%),每个 SM 8 个 warp 。
矩阵乘法(无张量核)如果我们想做一个 A*B=C 的矩阵乘法,其中每个矩阵的大小是 32×32,那么我们会希望将反复访问的内存加载到共享内存中,因为它的延迟大约是前者的 1/10(200cycle vs 20 cycle) 。通常,共享内存中的内存块被称为 memory tile 或只是 tile 。使用 2*32 warp,可以并行地将两个 32 *32 浮点数矩阵加载到共享内存块中 。我们有 8 个 SM,每个 SM 有 8 个 warp,因此,得益于并行化,我们只需要执行一次从全局内存到共享内存的顺序加载,这需要 200 个 cycle 。
为了进行矩阵乘法,我们现在需要从共享内存 A 和共享内存 B 加载一个包含 32 个数值的向量,并执行一个融合乘加(FFMA) 。然后将输出存储在寄存器 C 中 。我们将工作划分为这样一种方式,即每个 SM 做 8x 点积(32×32)来计算 C 的 8 个输出 。为什么这恰好是 8(在旧算法中是 4)有很强的技术性 。这一点,我建议你阅读 Scott Gray 关于矩阵乘法的博文来理解 。这意味着,我们有 8 次共享内存访问,每次 20 个 cycle,8 次 FFMA 操作,每次 4 个 cycle 。因此,总开销是:
200 cycle(全局内存)+ 8*20 cycle(共享内存)+ 8*4 cycle(FFMA)= 392 cycle
下面让我们看下使用张量核时需要多少开销 。
矩阵乘法(有张量核)利用张量核,我们可以在一个 cycle 内执行 4×4 矩阵乘法 。要做到这一点,我们首先需要把内存读到张量核中 。与上面类似,我们需要从全局内存(200 cycle)读取数据并存储在共享内存中 。要做一个 32×32 矩阵乘法,我们需要执行 8×8=64 次张量核运算 。一个 SM 有 8 个张量核,因此,我们总共有 64 个张量核——这正是我们需要的数量!我们可以通过 1 次内存传输(20 cycle)将数据从共享内存传输到张量核,然后进行 64 次并行张量核操作(1 cycle) 。这意味着,在这种情况下,张量核矩阵乘法的总开销为:


推荐阅读