大家好,我是呼噜噜,在计算机的早期,Intel奔腾处理器时代,他们的主板上的单个处理器CPU是相当大的。为了提升计算机的整体运算处理能力,一般是在主板上安装更多这样的处理器,这样就可以轻松突破晶体管限制。
物理CPU,是硬件上的CPU, 也是主板上CPU的插槽个数,是计算机上实际配置的CPU个数
我们在linux下可以通过指令 cat /proc/cpuinfo | grep 'physical id'| sort| uniq |wc -l来查看我们计算机的物理CPU个数
在windows下,我们可以在cmd命令中输入systeminfo,查看CPU个数
物理CPU通过连接器或插槽与其他主板元件通信,通过系统总线完成与系统的不同处理器之间的通信,但是系统总线的传输速度比起CPU的速度来说,是非常慢的通常导致出现瓶颈,使得无法充分利用每个CPU提供的计算能力。
所以工程师想 能不能让处理器中的核心组件小型化,并将它们封装在单个芯片中,这些就是物理内核,可以看作是计算单元
CPU核数,物理上真实的cpu核,有独立的电路元件以及L1,L2缓存,可以独立地执行指令。 通常每个CPU下的核数都是固定的,如果我们的计算机有两个物理CPU,每个CPU是双核的,那么计算机总共就是四核的。
在linux下,我们可以通过指令cat /proc/cpuinfo | grep "cpu cores" | wc -l来统计CPU核数。
在windows下,可以通过任务管理器查看:
我们分别看下,单核CPU和多核CPU的架构图:
为了弥补 CPU 与内存两者之间的性能差异,就在 CPU 内部引入了CPU Cache,也称高速缓存。 CPU Cache用的是 SRAM(Static Random-Access Memory)的芯片,也叫静态随机存储器。其只要有电,数据就可以保持存在,而一旦断电,数据就会丢失。
CPU Cache 通常分为大小不等的三级缓存,分别是 L1 Cache、L2 Cache 和 L3 Cache
部件 |
CPU访问所需时间 |
备注 |
L1 高速缓存 |
2~4 个时钟周期 |
每个 CPU 核心都有一块属于自己的 L1 高速缓存,L1 高速缓存通常分成指令缓存和数据缓存。 |
L2 高速缓存 |
10~20 个时钟周期 |
L2 高速缓存同样是每个 CPU 核心都有的 |
L3 高速缓存 |
20~60个时钟周期 |
L3 高速缓存是多个 CPU 核心共用的 |
我们可以发现越靠近 CPU 核心的缓存其访问速度越快,容量也越来越小。缓存读取数据过程。就像数据库缓存一样,首先在最快的缓存中找数据,如果缓存没有命中(Cache miss) 则往下一级找, 直到三级缓存都找不到时,最后会去内存找数据。
在历史上,为了提升CPU的性能,引入超标量、乱序运行、大量的寄存器及寄存器重命名、多指令解码器、预测运行、高速缓存等特性,这些特性从而让CPU拥有大量资源,并且CPU还能智能的预测执行指令。这就导致实际上CPU在大多数时间上,其资源是被闲置的,浪费是可耻的。
更多精彩文章在公众号「小牛呼噜噜」
为了进一步压榨CPU的性能,工程师发现,完全可以通过复制一些CPU内部组件,例如寄存器或一级缓存,来运行第二个线程,让这些闲置资源运行在另一个线程上。虽然只有一个物理CPU,但操作系统被提供了两个"逻辑CPU" ,而不是单个CPU,这样就成功使得操作系统被"欺骗"了。
操作系统可以使用逻辑CPU来模拟出真实CPU的效果。在从前没有多核处理器的时候,一个物理CPU只有一个物理内核,而现在有了多核技术,让物理核通过高速运算,让应用程序以为有两个CPU在运算,这样就可以把一个物理CPU当作多个"CPU"使用,即逻辑CPU
一般情况下,逻辑CPU=物理CPU个数*每颗核数,如果我们的电脑CPU支持超线程技术且开启的话,逻辑CPU的个数是核数的2倍,逻辑CPU=物理CPU个数*每颗核数*2,超线程技术可以使得 处理器中的1 颗内核在操作系统中,如同2 颗内核那样发挥作用。
还有一个我们需要知道:逻辑处理器个数 = CPU的线程数,也就是说有多少个逻辑处理器,就可以开多少个线程。对于一个CPU,线程数总是大于或等于核心数的。一个核心最少对应一个线程,但通过超线程技术,一个核心可以对应两个线程,也就是说它可以同时运行两个线程。
一般来说,物理CPU个数×每颗核数应该等于逻辑CPU的个数,如果不相等的话,则表示windows电脑的CPU支持超线程技术。
CPU的线程数概念仅仅只针对Intel的CPU , 对于AMD的CPU来说,只有核心数的概念,没有线程数的概念。因为其是通过Intel超线程技术来实现的,Intel早在2002年推出的Northwood奔腾4 HT处理器就把这一技术带入到消费级市场。
超线程技术(SMT),就是可以把一个物理线程模拟出两个线程来使用,使得单个核心用起来像两个核一样,以充分发挥CPU的性能。
我们需要先了解一下,线程和进程的概念
进程:
进程可以看作是程序的一次执行过程。一个程序的运行需要CPU时间、内存空间、文件以及I/O等资源。操作系统就是以进程为单位来分配这些资源的,所以说进程是操作系统中资源分配的基本单位。进程之间的资源是独立隔离的,能很好的进行资源管理和保护。 进程也是一个动态的过程:有它自身的产生,存在和消亡的过程
线程:
线程是进程中的一个执行任务(控制单元),负责当前进程中程序的执行。一个进程可以包含多个线程,至少包含一个线程,与进程不同的是多个线程之间资源数据是共享的。所以系统在产生一个线程,或是在各个线程之间作切换工作时,负担要比进程小得多,也正因为如此,线程也被称为轻量级进程。为了提高系统的执行效率,减少处理器的空转时间和调度切换的时间,线程取代了进程调度资源的基本功能,所以线程是资源调度的基本单位
CPU之所以要增加线程数,是源于多任务处理的需要。线程数越多,越有利于同时运行多个程序,因为线程数等同于在某个瞬间CPU能同时并行处理的任务数。
超线程的原理其实是:由于CPU和寄存器,缓存,主存、硬盘的读取速度的差异不是一个数量级的,CPU非常快
比如主频为3.0GHZ的CPU,一个时钟周期大约是0.3纳秒,内存访问大约需要120纳秒,固态硬盘访问大约需要50-150微秒,机械硬盘访问大约需要1-10毫秒,最后网络访问最慢,得几十毫秒左右。 如果我们把一个时钟周期如果按1秒算的话,内存访问大约就是6分钟 ,固态硬盘大约是2-6天 ,传统硬盘大约是1-12个月,网络访问就得几年了!
更多精彩文章在公众号「小牛呼噜噜」
这就给了我们超线程技术,将CPU内部暂时闲置处理资源充分“调动”起来,使得CPU中看起来同时有2个逻辑核,在同时工作的可能性。
我们知道CPU是采用指令流水线的方式来执行任务,在一个逻辑核等待指令执行的间隔(等待从cache或内存中获取下一条指令),把时间片分配到另一个逻辑核。物理CPU高速地在这两个逻辑核之间切换,让操作系统感知不到这个间隔,实现了“同时执行多个任务”
像奔腾4 HT处理器多加入了一个逻辑处理单元,这让CPU可以同时执行多个程序而共享一颗CPU内的资源,如:ALU、FPU、 缓存等,当两个线程都同时需要某一个资源时,其中一个要暂时停止,并让出资源,直到这些资源闲置后才能继续,所以单个物理CPU开启超线程的性能并不能等于两颗CPU的处理能力。
超线程技术只增加了5%的芯片面积,就可换来15%~30%的性能提升,而后来的Nehalem架构带来了全新的超线程技术,得益于指令集分制预测技术与较短的流水线,它拥有比奔腾4好得多的效能,再加上整合了内存控制器让其拥有更大的内存带宽,还有更大的缓存,这样就更能够有效的发挥超线程的作用,Nehalem的超线程可以在增加很少能耗的情况下,让性能提升20-30%,后续每一代虽然都有一些小修改,不过基本上都是Nehalem架构的延续。
虽然超线程能让计算机核数增加,但实际上计算机的核数翻倍并不能简单地认为着计算机的性能也翻倍了,计算机的性能还受CPU主频、机器字长、指令字长、存储字长、主存、I/O速度、硬盘速度等因素影响,也不意味着核数越多计算机性能会越来越好,因为超线程只是充分利用了CPU的空闲资源,提升了CPU利用率
我们再举个例子来理解一下逻辑CPU的概念:假设计算机有一个物理CPU,是2核的,支持超线程。那么这台计算机就是2核4线程的(4线程中线程数量也对应着逻辑CPU的数量)。 所以两路(两路指的是有两个物理CPU)四核超线程就有2*4*2=16个逻辑CPU。有人也把它称之为16核,实际上在linux的/proc/cpuinfo中查看只有8核。
cat /proc/cpuinfo | grep "processor" | wc -l来查看逻辑CPU数。
呼噜噜的2台电脑比较垃圾,没法把开超线程的图贴给大家看看,大家可以自己去试试
参考:
《深入理解计算机系统》
https://www.expreview.com/56674.html
本篇文章到这里就结束啦,如果我的文章对你有所帮助的话,还请点个免费的赞,你的支持会激励我输出更高质量的文章,感谢!
原文镜像:
https://mp.weixin.qq.com/s/JzLUgh47zAT5sD9dieNdog