上一篇请移步【动手学深度学习PyTorch版】22续 ResNet为什么能训练出1000层的模型_水w的博客-CSDN博客
目录
1.2 如何提升cpu的利用率?(如何使运算在cpu上进行的更快,特别是数值运算:矩阵乘法、线性运算等)

(1)CPU(处理器):除了运行操作系统和其他许多功能外,还能执行程序;通常由 8 个或者更多个核心组成。
(2)内存(随机访问存储,RAM):用于存储和检索计算结果,如权重向量和激活参数,以及训练数据。
(3)以太网:一个或者多个,速度从 1 GB/s 到 100 GB/s 不等。
(4)高速扩展总线(PCle):用于系统连接一个或者多个 GPU;服务器最多有 8 个加速卡,通常以更高级的拓扑方式连接,而桌面系统则有 1 个或 2 个加速卡,具体取决于用户的预算和电源负载的大小。
(5)持久性存储设备:为系统需要的训练数据和中间检查点需要的存储提供了足够的传输速度;如磁盘驱动器、固态驱动器,在许多情况下使用高速扩展总线连接。
程序执行的原理:在计算机上运行代码的时候,需要将数据转移到处理器(GPU 或者 CPU)上执行计算,然后将结果从处理器转移回到随机访问存储和持久访问存储器中。

CPU(处理器):除了运行操作系统和其他许多功能外,还能执行程序;通常由 8 个或者更多个核心组成。
CPU的芯片图:

主要用于存储需要随时访问的数据
当想要从内存中读取一部分内容时,需要先将地址(信息的位置)发送到 RAM,然后可以选择只读取一条 64 位记录还是一长串记录(突发读取,burst read),
当拥有多个存储体时,每个存储体大部分时候都可以独立地读取内存,
因为 GPU 的处理单元比 CPU 多得多,因此它对内存带宽的需要也更高,
随机访问存储的一些关键特性是带宽(bandwidth)和延迟(latency),存储设备也是如此,只是不同设备之间的特性差异可能更大。
(1)硬盘驱动器(hard disk drive,HDD)
它包含许多旋转的盘片,这些盘片的磁头可以放置在任何给定的磁道上进行读写,
优点是相对便宜,:缺点:
(2)固态驱动器(solid state drives,SSD)
固态驱动器使用闪存持久存储信息以更快地访问存储的记录,
缺点是:
(1)组成:
前端加载指令并尝试预测将采用哪条路径,然后将指令从汇编代码解码为微指令(汇编代码通常不是处理器执行的最低级别代码,复杂的微指令可以被解码成一组更低级的操作,然后由实际的执行核心处理,通常执行核心能够同时执行许多操作)。
高效的程序可以在每个时钟周期内执行多条指令,前提是这些指令可以独立执行。
为了提高吞吐量,处理器还可以在分支指令中同时执行多条代码路径,然后丢弃未选择分支的结果。
总线会因为处理器型号、各代产品和供应商之间的特定拓扑结构有明显不同。
为了避免出现向 CPU 传输用于处理的数据不足的情况,应该尽量避免从内存中加载新数据,而是应该将数据放在 CPU 的缓存上。
添加缓存一方面能够确保处理器核心不缺乏数据,但同时也增加了芯片的尺寸,消耗了原本可以用来提高处理能力的面积。
CPU在一个时钟周期内执行许多操作,是通过向量处理单元实现的(这些处理单元有不同的名称:在 ARM 上叫做 NEON,在 x86 上被称为 AVX2),常见的功能是能够执行单指令多数据操作(single instruction multiple data,SIMD)。
从图中我们可以看到,一个数据要参与计算,需要走很长的一条路。
如果要计算两个向量的和a+b,在计算之前需要准备数据,a 和b很有可能是放在主内存中的,如果想要将a和b进行相加,就需要将数据从主内存搬运到寄存器中(数据只有被搬运到寄存器中才能参与运算):主内存=>L3 cache(shared LLC)=>L2 cache=>L1 cache=>寄存器。
这条路里面,每一个地方的能其实是不一样的。这条路径中最快的是寄存器,寄存器可以认为是和主频一样快,

虽然cpu算的比较快、频率比较高,但实际上,实测下来,在实际测试的时候会发现远远没有达到CPU理论的算的速度,运算速度可能远低于理论值,这通常是由于内存访问速度过慢导致的。
内存访问太慢了,所以一般来说,我们所谓的加速一个比较大的关键点就是提升空间和时间的内存本地性,来使得我的缓存的效率更高。
具体来说,有两种办法:
提升时间上的本地性:重用数据使得保持在他们的缓存里(计算时需要将数据从主内存搬运到寄存器中,如果计算完的数据不再使用,cpu会将数据从寄存器一直回退到主内存中,因此,对于重复使用的数据,就希望能够将重复使用的数据一直保持在寄存器或者是L1中,以便于下一次使用)。
提升空间上的本地性:按序读写数据使得可以预读取(cpu在读取内存的时候是一块一块地读,如果所要计算的数据如果在内存中是存储在一起的话,就希望下一次计算所使用到的数据和前一次计算所需要的数据是相邻的,这样能够提升cpu读取数据的效率)。
比如,例:

如果一个矩阵是按行存储的(在行上面的内存地址是连续的),访问一行会比访问一列要快,特别是当矩阵比较大的情况下。这是因为,
高端cpu有几十个核,比如:

加起来一共是64个核。
但是Intel比较有意思的是,假设从芯片上来说有4个物理核,但是从系统上你看到的核可能是有8个,因为它使用了超线程。把一个CPU超线程了两个核。
但是超线程对于计算密集型没有太多的用处,并行来利用所有核,超线程不一定提升性能,因为这2个超线程共享的是一个寄存器。
例:使用以下两种方式来计算a + b ,

左边使用循环对元素进行逐个相加,同样的道理,图的右边是使用计算框架(numpy等)进行加法运算,最终在运算的时候左边会比右边慢很多,慢个几百倍。
那是因为有2个原因:


这个是Ncidia Titan X的一个架构图, 我们可以认为一小块就是一个核。其实3080,3070,3090等等没什么区别,唯一区别就是放了不同的大核而已。
大核里面有很多小核,每个小核的每一个绿点,它其实我们可以认为是一个计算单元,可以在每一个绿点上开一个线程。所以GPU来说,每次可以上千次计算。
就算每一个绿点的计算能力比cpu弱,速度慢上4,5倍,但是计算单元数量多,最终还是快的。

表中的“/”表示一般型号的参数/高端型号的参数。CPU的核心数量一般来说是6核,好一点的是64。而显卡的核心数量一般来说是2K核,好一点的是4K个。
GPU的核心数量远多于CPU,所以就导致了GPU每秒能计算的浮点数(TFLOPS,可以用核心数量和主频的乘积来做一个简单的近似)就要远高于CPU。
每一次计算都需要从内存中读取数据,因此内存带宽也很重要,通常来说,如果达不到计算峰值一般是由于内存带宽的限制。
也就是说,GPU通过高的内核带宽,多核,来换取它的计算更快。核心数量和内存带宽的优势使得GPU在运算速度上要远快于CPU。但是另外付出的代价是,这也导致了GPU的内存大小不是很大,GPU的控制流很弱(CPU是做通用计算的,因此需要很强的控制流)。
本质上与cpu一样,
(1)并行:使用数千个线程;
(2)内存本地性:
缓存更小,架构更简单(GPU为了节省面积将缓存做得比较小,这样做的好处是内存的带宽会更高一点);
(3)少用控制语句:支持有限,同步开销很大;

CPU和GPU并不是独立的,所有的任务都是运行在CPU上的,如果要在GPU上做运算,就会存在带宽的问题。
因此不要频繁地在CPU和GPU之间传递数据:带宽限制,同步开销(这里的同步是由驱动决定的)。

(1)C++或者任何高性能语言:编译器成熟;
(2)Nvidia上用CUDA:编译器和驱动成熟;
(3)其他使用OpenCL(CUDA也支持OpenCL):质量取决于硬件厂商(编译器和驱动是根据硬件厂商决定);
目录前言滤波电路科普主要分类实际情况单位的概念常用评价参数函数型滤波器简单分析滤波电路构成低通滤波器RC低通滤波器RL低通滤波器高通滤波器RC高通滤波器RL高通滤波器部分摘自《LC滤波器设计与制作》,侵权删。前言最近需要学习放大电路和滤波电路,但是由于只在之前做音乐频谱分析仪的时候简单了解过一点点运放,所以也是相当从零开始学习了。滤波电路科普主要分类滤波器:主要是从不同频率的成分中提取出特定频率的信号。有源滤波器:由RC元件与运算放大器组成的滤波器。可滤除某一次或多次谐波,最普通易于采用的无源滤波器结构是将电感与电容串联,可对主要次谐波(3、5、7)构成低阻抗旁路。无源滤波器:无源滤波器,又称
最近在学习CAN,记录一下,也供大家参考交流。推荐几个我觉得很好的CAN学习,本文也是在看了他们的好文之后做的笔记首先是瑞萨的CAN入门,真的通透;秀!靠这篇我竟然2天理解了CAN协议!实战STM32F4CAN!原文链接:https://blog.csdn.net/XiaoXiaoPengBo/article/details/116206252CAN详解(小白教程)原文链接:https://blog.csdn.net/xwwwj/article/details/105372234一篇易懂的CAN通讯协议指南1一篇易懂的CAN通讯协议指南1-知乎(zhihu.com)视频推荐CAN总线个人知识总
深度学习部署:Windows安装pycocotools报错解决方法1.pycocotools库的简介2.pycocotools安装的坑3.解决办法更多Ai资讯:公主号AiCharm本系列是作者在跑一些深度学习实例时,遇到的各种各样的问题及解决办法,希望能够帮助到大家。ERROR:Commanderroredoutwithexitstatus1:'D:\Anaconda3\python.exe'-u-c'importsys,setuptools,tokenize;sys.argv[0]='"'"'C:\\Users\\46653\\AppData\\Local\\Temp\\pip-instal
我完全不是程序员,正在学习使用Ruby和Rails框架进行编程。我目前正在使用Ruby1.8.7和Rails3.0.3,但我想知道我是否应该升级到Ruby1.9,因为我真的没有任何升级的“遗留”成本。缺点是什么?我是否会遇到与普通gem的兼容性问题,或者甚至其他我不太了解甚至无法预料的问题? 最佳答案 你应该升级。不要坚持从1.8.7开始。如果您发现不支持1.9.2的gem,请避免使用它们(因为它们很可能不被维护)。如果您对gem是否兼容1.9.2有任何疑问,您可以在以下位置查看:http://www.railsplugins.or
如何学习ruby的正则表达式?(对于假人) 最佳答案 http://www.rubular.com/在Ruby中使用正则表达式时是一个很棒的工具,因为它可以立即将结果可视化。 关于ruby-我如何学习ruby的正则表达式?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/1881231/
深度学习12.CNN经典网络VGG16一、简介1.VGG来源2.VGG分类3.不同模型的参数数量4.3x3卷积核的好处5.关于学习率调度6.批归一化二、VGG16层分析1.层划分2.参数展开过程图解3.参数传递示例4.VGG16各层参数数量三、代码分析1.VGG16模型定义2.训练3.测试一、简介1.VGG来源VGG(VisualGeometryGroup)是一个视觉几何组在2014年提出的深度卷积神经网络架构。VGG在2014年ImageNet图像分类竞赛亚军,定位竞赛冠军;VGG网络采用连续的小卷积核(3x3)和池化层构建深度神经网络,网络深度可以达到16层或19层,其中VGG16和VGG
文章目录1、自相关函数ACF2、偏自相关函数PACF3、ARIMA(p,d,q)的阶数判断4、代码实现1、引入所需依赖2、数据读取与处理3、一阶差分与绘图4、ACF5、PACF1、自相关函数ACF自相关函数反映了同一序列在不同时序的取值之间的相关性。公式:ACF(k)=ρk=Cov(yt,yt−k)Var(yt)ACF(k)=\rho_{k}=\frac{Cov(y_{t},y_{t-k})}{Var(y_{t})}ACF(k)=ρk=Var(yt)Cov(yt,yt−k)其中分子用于求协方差矩阵,分母用于计算样本方差。求出的ACF值为[-1,1]。但对于一个平稳的AR模型,求出其滞
写在之前Shader变体、Shader属性定义技巧、自定义材质面板,这三个知识点任何一个单拿出来都是一套知识体系,不能一概而论,本文章目的在于将学习和实际工作中遇见的问题进行总结,类似于网络笔记之用,方便后续回顾查看,如有以偏概全、不祥不尽之处,还望海涵。1、Shader变体先看一段代码......Properties{ [KeywordEnum(on,off)]USL_USE_COL("IsUseColorMixTex?",int)=0 [Toggle(IS_RED_ON)]_IsRed("IsRed?",int)=0}......//中间省略,后续会有完整代码 #pragmamulti_c
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visitthehelpcenter指导。关闭9年前。我来自C、php和bash背景,很容易学习,因为它们都有相同的C结构,我可以将其与我已经知道的联系起来。然后2年前我学了Python并且学得很好,Python对我来说比Ruby更容易学。然后从去年开始,我一直在尝试学习Ruby,然后是Rails,我承认,直到现在我还是学不会,讽刺的是那些打着简单易学的烙印,但是对于我这样一个老练的程序员来说,我只是无法将它
进行这种深度检查的最佳方法是什么:{:a=>1,:b=>{:c=>2,:f=>3,:d=>4}}.include?({:b=>{:c=>2,:f=>3}})#=>true谢谢 最佳答案 我想我从那个例子中明白了你的意思(不知何故)。我们检查子哈希中的每个键是否在超哈希中,然后检查这些键的对应值是否以某种方式匹配:如果值是哈希,则执行另一次深度检查,否则,检查值是否相等:classHashdefdeep_include?(sub_hash)sub_hash.keys.all?do|key|self.has_key?(key)&&ifs