• 深度学习入门(三十七)计算性能——硬件(TBC)


    前言

    核心内容来自博客链接1博客连接2希望大家多多支持作者
    本文记录用,防止遗忘
    未完成,感觉不是很重要

    计算性能——硬件(CPU、GPU)

    课件

    电脑

    Intel i7:0.15T FLOPS
    DDR4:32GB
    NVIDIA TitanX:12T FLOPS、16GB


    Intel i7-6700K
    在这里插入图片描述

    提升CPU利用率①

    在计算 a + b a+b a+b之前,需要准备数据

    • 主内存 -> L3 -> L2 -> L1 -> 寄存器
    • Ll访问延时:0.5 ns
    • L2访问延时:7ns (14 × L1)
    • 主内存访问延时:100ns (200 × L1)
    • 提升空间和时间的内存本地性
    • 时间:重用数据使得保持它们在缓存里
    • 空间:按序读写数据使得可以预读取

    • 样例分析: 如果一个矩阵是按列存储,访问一行会比访问一列要快
    • CPU一次读取64字节(缓存线)
    • CPU会“聪明的”提前读取下一个(缓存线)
    • 在这里插入图片描述

      提升CPU利用率②

      高端CPU有几十个核

    • EC2 P3.16xlarge: 2 Intel Xeon CPUs,32物理核
    • 并行来利用所有核
    • 超线程不一定提升性能,因为它们共享寄存器

    • 样例分析: 左边比右边快(python) ![在这里插入图片描述](https://img-blog.csdnimg.cn/b685a431ad0742988d8b01794e4d5e24.png)

      左边调用n次函数,每次调用有开销
      右边很容易被并行(例如下面C++实现)
      在这里插入图片描述
      Nvidia Titan X (Pascal)

      在这里插入图片描述

      CPU VS GPU

      6/642K/4K
      TFLOPS0.2/110/100
      内存大小32GB/1TB16GB/32GB
      内存带宽30 GB/s / 100 GB/s400 GB/s / 1 TB/s
      控制流

      提升GPU利用率

      并行

    • 使用数千个线程
    • 内存本地性
    • 缓存更小,架构更加简单。
    • 少用控制语句
    • 支持有限
    • 同步开销很大
    • CPU/GPU带宽

      不要频繁在CPU和GPU之前传数据:带宽限制,同步开销

      在这里插入图片描述

      更多的CPU和GPU

      CPU:AMD,ARM
      GPU:AMD,Intel,ARM,Qualcomm

      CPU/GPU高性能计算编程

      CPU: C++或者任何高性能语言

    • 编译器成熟
    • GPU
    • Nvidia上用CUDA:编译器和驱动成熟
    • 其他用OpenCL:质量取决于硬件厂商
    • 总结

      1、CPU:可以处理通用计算。性能优化考虑数据读写效率和多线程
      2、GPU:使用更多的小核和更好的内存带宽,适合能大规模并行的计算任务

      教材

      很好地理解算法和模型才可以捕获统计方面的问题,构建出具有出色性能的系统。同时,至少对底层硬件有一定的了解也是必不可少的。本节不能替代硬件和系统设计的相关课程。相反,本节的内容可以作为理解某些算法为什么比其他算法更高效以及如何实现良好吞吐量的起点。一个好的设计可以很容易地在性能上造就数量级的差异,这也是后续产生的能够训练网络(例如,训练时间为1周)和无法训练网络(训练时间为3个月,导致错过截止期)之间的差异。我们先从计算机的研究开始。然后深入查看CPU和GPU。最后,再查看数据中心或云中的多台计算机的连接方式。
      在这里插入图片描述

      1 计算机

      大多数深度学习研究者和实践者都可以使用一台具有相当数量的内存、计算资源、某种形式的加速器(如一个或者多个GPU)的计算机。计算机由以下关键部件组成:

    • 一个处理器(也被称为CPU),它除了能够运行操作系统和许多其他功能之外,还能够执行我们给它的程序,通常由8个或更多个核心组成。
    • 内存(随机访问存储,RAM)用于存储和检索计算结果,如权重向量和激活参数,以及训练数据。
    • 一个或多个以太网连接,速度从1GB/s到100GB/s不等。在高端服务器上可能用到更高级的互连。
    • 高速扩展总线(PCIe)用于系统连接一个或多个GPU。服务器最多有8个加速卡,通常以更高级的拓扑方式连接,而桌面系统则有1个或2个加速卡,具体取决于用户的预算和电源负载的大小。
    • 持久性存储设备,如磁盘驱动器、固态驱动器,在许多情况下使用高速扩展总线连接。它为系统需要的训练数据和中间检查点需要的存储提供了足够的传输速度。
    • 在这里插入图片描述
      如 图12.4.2所示,高速扩展总线由直接连接到CPU的多个通道组成,将CPU与大多数组件(网络、GPU和存储)连接在一起。例如,AMD的Threadripper3有64个PCIe4.0通道,每个通道都能够双向传输16Gbit/s的数据。内存直接连接到CPU,总带宽高达100GB/s。

      当我们在计算机上运行代码时,我们需要将数据转移到处理器上(CPU或GPU)执行计算,然后将结果从处理器移回到随机访问存储和持久存储器中。因此,为了获得良好的性能,我们需要确保每一步工作都能无缝链接,而不希望系统中的任何一部分成为主要的瓶颈。例如,如果不能快速加载图像,那么处理器就无事可做。同样地,如果不能快速移动矩阵到CPU(或GPU)上,那么CPU(或GPU)就会无法全速运行。最后,如果希望在网络上同步多台计算机,那么网络就不应该拖累计算速度。一种选择是通信和计算交错进行。

      2 内存

      最基本的内存主要用于存储需要随时访问的数据。目前,CPU的内存通常为DDR4类型,每个模块提供20-25Gb/s的带宽。每个模块都有一条64位宽的总线。通常使用成对的内存模块来允许多个通道。CPU有2到4个内存通道,也就是说,它们内存带宽的峰值在40GB/s到100GB/s之间。一般每个通道有两个物理存储体(bank)。例如AMD的Zen 3 Threadripper有8个插槽。

      虽然这些数字令人印象深刻,但实际上它们只能说明了一部分故事。当我们想要从内存中读取一部分内容时,我们需要先告诉内存模块在哪里可以找到信息。也就是说,我们需要先将地址(address)发送到RAM。然后我们可以选择只读取一条64位记录还是一长串记录。后者称为突发读取(burst read)。概括地说,向内存发送地址并设置传输大约需要100ns(细节取决于所用内存芯片的特定定时系数),每个后续传输只需要0.2ns。总之,第一次读取的成本是后续读取的500倍!请注意,我们每秒最多可以执行一千万次随机读取。这说明应该尽可能地避免随机内存访问,而是使用突发模式读取和写入。

      3 存储器

      我们看到随机访问存储的一些关键特性是 带宽(bandwidth)和 延迟(latency)。存储设备也是如此,只是不同设备之间的特性差异可能更大。

      3.1 硬盘驱动器

      硬盘驱动器(hard disk drive,HDD)已经使用了半个多世纪。简单的说,它们包含许多旋转的盘片,这些盘片的磁头可以放置在任何给定的磁道上进行读写。高端磁盘在9个盘片上可容纳高达16TB的容量。硬盘的主要优点之一是相对便宜,而它们的众多缺点之一是典型的灾难性故障模式和相对较高的读取延迟。

      要理解后者,请了解一个事实即硬盘驱动器的转速大约为7200RPM(每分钟转数)。它们如果转速再快些,就会由于施加在碟片上的离心力而破碎。在访问磁盘上的特定扇区时,还有一个关键问题:需要等待碟片旋转到位(可以移动磁头,但是无法对磁盘加速)。因此,可能需要8毫秒才能使用请求的数据。一种常见的描述方式是,硬盘驱动器可以以大约100IOPs(每秒输入/输出操作)的速度工作,并且在过去二十年中这个数字基本上没变。同样糟糕的是,带宽(大约为100-200MB/s)也很难增加。毕竟,每个磁头读取一个磁道的比特,因此比特率只随信息密度的平方根缩放。因此,对于非常大的数据集,HDD正迅速降级为归档存储和低级存储。

      3.2 固态驱动器

      固态驱动器(solid state drives,SSD)使用闪存持久地存储信息。这允许更快地访问存储的记录。现代的固态驱动器的IOPs可以达到10万到50万,比硬盘驱动器快3个数量级。而且,它们的带宽可以达到1-3GB/s,比硬盘驱动器快一个数量级。这些改进听起来好的难以置信,而事实上受固态驱动器的设计方式,它仍然存在下面的附加条件:

    • 固态驱动器以块的方式(256KB或更大)存储信息。块只能作为一个整体来写入,因此需要耗费大量的时间,导致固态驱动器在按位随机写入时性能非常差。而且通常数据写入需要大量的时间还因为块必须被读取、擦除,然后再重新写入新的信息。如今固态驱动器的控制器和固件已经开发出了缓解这种情况的算法。尽管有了算法,写入速度仍然会比读取慢得多,特别是对于QLC(四层单元)固态驱动器。提高性能的关键是维护操作的“队列”,在队列中尽可能地优先读取和写入大的块。
    • 固态驱动器中的存储单元磨损得比较快(通常在几千次写入之后就已经老化了)。磨损程度保护算法能够将退化平摊到许多单元。也就是说,不建议将固态驱动器用于交换分区文件或大型日志文件。
    • 最后,带宽的大幅增加迫使计算机设计者将固态驱动器与PCIe总线相连接,这种驱动器称为NVMe(非易失性内存增强),其最多可以使用4个PCIe通道。在PCIe4.0上最高可达8GB/s。
    • 3.3 云存储

      云存储提供了一系列可配置的性能。也就是说,虚拟机的存储在数量和速度上都能根据用户需要进行动态分配。我们建议用户在延迟太高时(例如,在训练期间存在许多小记录时)增加IOPs的配置数。

      4 CPU

      中央处理器(central processing unit,CPU)是任何计算机的核心。它们由许多关键组件组成:处理器核心(processor cores)用于执行机器代码的、总线(bus)用于连接不同组件(注意,总线会因为处理器型号、各代产品和供应商之间的特定拓扑结构有明显不同)和缓存(cach)相比主内存实现更高的读取带宽和更低的延迟内存访问。最后,因为高性能线性代数和卷积运算常见于媒体处理和机器学习中,所以几乎所有的现代CPU都包含向量处理单元(vector processing unit)为这些计算提供辅助。
      在这里插入图片描述

      4.1 微体系结构

      每个处理器核心都由一组相当复杂的组件组成。虽然不同时代的产品和供应商的细节有所不同,但基本功能都是标准的。前端加载指令并尝试预测将采用哪条路径(例如,为了控制流),然后将指令从汇编代码解码为微指令。汇编代码通常不是处理器执行的最低级别代码,而复杂的微指令却可以被解码成一组更低级的操作,然后由实际的执行核心处理。通常执行核心能够同时执行许多操作,例如,下图的ARM Cortex A77核心可以同时执行多达8个操作。
      在这里插入图片描述
      这意味着高效的程序可以在每个时钟周期内执行多条指令,前提是这些指令可以独立执行。不是所有的处理单元都是平等的。一些专用于处理整数指令,而另一些则针对浮点性能进行了优化。为了提高吞吐量,处理器还可以在分支指令中同时执行多条代码路径,然后丢弃未选择分支的结果。这就是为什么前端的分支预测单元很重要,因为只有最有希望的路径才会被继续执行。

      4.2 矢量化
      4.3 缓冲

      5 GPU和其他加速卡

      毫不夸张地说,如果没有GPU,深度学习就不会成功。基于同样的原因,有理由认为GPU制造商的财富由于深度学习而显著增加。这种硬件和算法的协同进化导致了这样一种情况:无论好坏,深度学习都是更可取的统计建模范式。

      6 网络和总线

      每当单个设备不足以进行优化时,我们就需要来回传输数据以实现同步处理,于是网络和总线就派上了用场。我们有许多设计参数:带宽、成本、距离和灵活性。应用的末端我们有WiFi,它有非常好的使用范围,非常容易使用(毕竟没有线缆),而且还便宜,但它提供的带宽和延迟相对一般。

    • PCIe,一种专用总线,用于每个通道点到点连接的高带宽需求(在16通道插槽中的PCIe4.0上高达32GB/s),延迟时间为个位数的微秒(5μs)。PCIe链接非常宝贵。处理器拥有的数量:AMD的EPYC 3有128个通道,Intel的Xeon每个芯片有48个通道;在桌面级CPU上,数字分别是20(Ryzen9)和16(Core i9)。由于GPU​通常有16个通道,这就限制了以全带宽与CPU连接的GPU数量。毕竟,它们还需要与其他高带宽外围设备(如存储和以太网)共享链路。与RAM访问一样,由于减少了数据包的开销,因此更适合大批量数据传输。
    • 以太网,连接计算机最常用的方式。虽然它比PCIe慢得多,但它的安装成本非常低,而且具有很强的弹性,覆盖的距离也要长得多。低级服务器的典型带宽为1GBit/s。高端设备(如云中的C5实例。这进一步增加了开销。与PCIe类似,以太网旨在连接两个设备,例如计算机和交换机。
    • 交换机,一种连接多个设备的方式,该连接方式下的任何一对设备都可以同时执行(通常是全带宽)点对点连接。例如,以太网交换机可能以高带宽连接40台服务器。请注意,交换机并不是传统计算机网络所独有的。甚至PCIe通道也可以是可交换的,例如:P2实例就是将大量GPU连接到主机处理器。
    • NVLink,是PCIe的替代品,适用于非常高带宽的互连。它为每条链路提供高达300Gbit/s的数据传输速率。服务器GPU(Volta V100)有六个链路。而消费级GPU(RTX 2080Ti)只有一个链路,运行速度也降低到100Gbit/s。我们建议使用NCCL来实现GPU之间的高速数据传输。
    • 7 小结

    • 设备有运行开销。因此,数据传输要争取量大次少而不是量少次多。这适用于RAM、固态驱动器、网络和GPU。
    • 矢量化是性能的关键。确保充分了解你的加速器的特定功能。例如,一些Intel Xeon CPU特别适用于INT8操作,NVIDIA Volta GPU擅长FP16矩阵操作,NVIDIA Turing擅长FP16、INT8和INT4操作。
    • 在训练过程中数据类型过小导致的数值溢出可能是个问题(在推断过程中则影响不大)。
    • 数据混叠现象会导致严重的性能退化。64位CPU应该按照64位边界进行内存对齐。在GPU上建议保持卷积大小对齐,例如:与张量核对齐。
    • 将算法与硬件相匹配(例如,内存占用和带宽)。将命中参数装入缓存后,可以实现很大数量级的加速比。
    • 在验证实验结果之前,我们建议先在纸上勾勒出新算法的性能。关注的原因是数量级及以上的差异。
    • 使用调试器跟踪调试寻找性能的瓶颈。
    • 训练硬件和推断硬件在性能和价格方面有不同的优点。
  • 相关阅读:
    【算法|前缀和系列No.1】牛客网 DP34 【模板】前缀和
    Encrypt 加密/解密
    linux工具篇
    分布式解决方案 Percolator--详解
    用PS给证件照换底色
    Python二维码生成工具
    多年测试经验分享:上市公司怎么进行安全测试
    操作系统内存换出---15
    DAY57 739. 每日温度 + 496.下一个更大元素 I
    Web的三大作用域详解
  • 原文地址:https://blog.csdn.net/qq_52358603/article/details/127873782