为了让程序能快点,特地了解了CPU的各种原理,比如多核、超线程、NUMA、睿频、功耗、GPU、大小核再到分支预测、cache_line失效、加锁代价、IPC等各种目的(都有对应的代码和测试数据)都会在这系列文章中失掉答案。当然肯定会有程序员最关心的分支预测案例、Disruptor无锁案例、cache_line伪共享案例等等。
这次让咱们从最底层的沙子开局用8篇文章来回答各种不懂以及少量的试验对比案例和测试数据。
大的方面重要是从这几个不懂来写这些文章:
CPU的制作和概念
PerfIPC以及CPU性能
CPU性能和CacheLine
十年后数据库还是不敢拥抱NUMA?
IntelPAUSE指令变动是如何影响自旋锁以及MySQL的性能的
Intel、海光、鲲鹏920、飞扬2500CPU性能对比
一次性海光物理机资源竞争压测的记载
飞扬ARM芯片(FT2500)的性能测试
IPC:insnspercycleinsn/cycles
cycles:CPU时钟周期。CPU从它的指令集(instructionset)当选用指令口头。
一个指令蕴含以下的步骤,每个步骤由CPU的一个叫做配置单元(functionalunit)的组件来启动处置,每个步骤的口头都至少要求破费一个时钟周期。
以上结构简化成流水线就是:
五个步骤只能串行, 然而可以做成pipeline优化效率 ,也就是第一个指令做第二步的时刻,指令读取单元可以去读取下一个指令了,假设有一个指令慢就会形成stall,也就是pipeline有中央卡壳了。
$sudoperfstat-a--sleep10Performancecounterstatsfor'systemwide':239866.330098task-clock(msec)#23.985CPUsutilized/10*1000(100.00%)45,709context-switches#0.191K/sec(100.00%)1,715cpu-migrations#0.007K/sec(100.00%)79,586page-faults#0.332K/sec3,488,525,170cycles#0.015GHz(83.34%)9,708,140,897stalled-cycles-frontend#278.29%/cyclesfrontendcyclesidle(83.34%)9,314,891,615stalled-cycles-backend#267.02%/cyclesbackendcyclesidle(66.68%)2,292,955,367instructions#0.66insnspercycleinsn/cycles#4.23stalledcyclesperinsnstalled-cycles-frontend/insn(83.34%)447,584,805branches#1.866M/sec(83.33%)8,470,791branch-misses#1.89%ofallbranches(83.33%)
stalled-cycles,则是指令管道未能按理想形态施展并行作用,出现停滞的时钟周期。stalled-cycles-frontend指指令读取或解码的指令步骤,而stalled-cycles-backend则是指令口头步骤。第二列中的cyclesidle其实意思跟stalled是一样的,由于指令口头停滞了,所以指令管道也就闲暇了,千万不要曲解为CPU的闲暇率。这个数值是由stalled-cycles-frontend或stalled-cycles-backend除以下面的cycles得出的。
另外cpu可以同时有多条pipeline,这就是实践上最大的IPC.
只管一个指令要求5个步骤,也就是齐全口头完要求5个cycles,这样一个时钟周期最多能口头0.2条指令,IPC就是0.2,显然太低了。
假设把多个指令的五个步骤用pipeline流水线跑起来,无理想状况下一个时钟周期就能跑完一条指令了,这样IPC就能到达1了。
进一步优化,假设咱们放大流水线的条数,让多个指令并行口头,就能失掉更高的IPC了,然而这种并行肯定会有指令之间的依赖,比如第二个指令依赖第一个的结果,所以多个指令并行更容易出现相互期待(stall).
普通而言流水线的超标量不能超越单条流水线的深度
每一个配置单元的流水线的长度是不同的。理想上,不同的配置单元的流水线长度原本就不一样。咱们往常所说的14级流水线,指的通常是启动整数计算指令的流水线长度。假设是浮点数运算,实践的流水线长度则会更长一些。
在第1条指令口头到访存(MEM)阶段的时刻,流水线里的第4条指令,在口头取指令(Fetch)的操作。访存和取指令,都要启动内存数据的读取。咱们的内存,只要一个地址译码器的作为地址输入,那就只能在一个时钟周期外面读取一条数据,没方法同时口头第1条指令的读取内存数据和第4条指令的读取指令代码。
把内存拆成两局部的处置打算,在计算机体系结构里叫作哈佛架构(HarvardArchitecture),来自哈佛大学设计MarkI型计算机时刻的设计。咱们当天经常使用的CPU,依然是冯·诺依曼体系结构的,并没有把内存拆成程序内存和数据内存这两局部。由于假设那样拆的话,对程序指令和数据要求的内存空间,咱们就没有方法依据实践的运行去灵活调配了。只管处置了资源抵触的疑问,然而也失去了灵敏性。
在流水线发生依赖的时刻肯定pipelinestall,也就是让依赖的指令口头NOP。
重要是经过采集PMU(PerformanceMonitoringUnit--CPU外部提供)数据来做性能监控
sudoperfrecord-g-a-eskb:kfree_skb//perf记载丢包调用栈而后sudoperfscript检查(网络报文被摈弃时会调用该函数kfree_skb)perfrecord-e'skb:consume_skb'-ag//记载网络消耗perfprobe--addtcp_sendmsg//参与监听probeperfrecord-eprobe:tcp_sendmsg-aRsleep1sudoperfschedrecord--sleep1//记载cpu调度的延时sudoperfschedlatency//检查
可以经过perf看到cpu的经常使用状况:
$sudoperfstat-a--sleep10Performancecounterstatsfor'systemwide':239866.330098task-clock(msec)#23.985CPUsutilized/10*1000(100.00%)45,709context-switches#0.191K/sec(100.00%)1,715cpu-migrations#0.007K/sec(100.00%)79,586page-faults#0.332K/sec3,488,525,170cycles#0.015GHz(83.34%)9,708,140,897stalled-cycles-frontend#278.29%/cyclesfrontendcyclesidle(83.34%)9,314,891,615stalled-cycles-backend#267.02%/cyclesbackendcyclesidle(66.68%)2,292,955,367instructions#0.66insnspercycleinsn/cycles#4.23stalledcyclesperinsnstalled-cycles-frontend/insn(83.34%)447,584,805branches#1.866M/sec(83.33%)8,470,791branch-misses#1.89%ofallbranches(83.33%)
实践运转的时刻参与如下nop到100个以上
voidmain(){while(1){__asm__("nop\n\t""nop\n\t""nop");}}
假设同时运转两个如上测试程序,鲲鹏920运转,每个程序的IPC都是3.99
#perfstat--./nop.outfailedtoreadcounterbranchesPerformancecounterstatsfor'./nop.out':8826.948260task-clock(msec)#1.000CPUsutilized8context-switches#0.001K/sec0cpu-migrations#0.000K/sec37page-faults#0.004K/sec22,949,862,030cycles#2.600GHz2,099,719stalled-cycles-frontend#0.01%frontendcyclesidle18,859,839stalled-cycles-backend#0.08%backendcyclesidle91,465,043,922instructions#3.99insnspercycle#0.00stalledcyclesperinsnbranches33,262branch-misses#0.00%ofallbranches8.827886000secondstimeelapsed
intelX868260
#perfstat--./nop.outPerformancecounterstatsfor'./nop.out':65061.160345task-clock(msec)#1.001CPUsutilized46context-switches#0.001K/sec92cpu-migrations#0.001K/sec108page-faults#0.002K/sec155,659,827,263cycles#2.393GHzstalled-cycles-frontendstalled-cycles-backend603,247,401,995instructions#3.88insnspercycle4,742,051,659branches#72.886M/sec1,799,428branch-misses#0.04%ofallbranches65.012821629secondstimeelapsed
这两块CPU实践IPC最大值都是4,实践x86离实践值更远一些.参与while循环中的nop数量(从132参与到432个)IPC能优化到3.92
ipc是指每个core的IPC
概念 :一个核还可以进一步分红几个逻辑核,来口头多个管理流程,这样可以进一步提高并行水平,这一技术就叫超线程,有时叫做simultaneousmulti-threading(SMT)。
超线程技术重要的登程点是,当处置器在运转一个线程,口头指令代码时,很多时刻处置器并不会经常使用到所有的计算才干,局部计算才干就会处于闲暇形态。而超线程技术就是经过多线程来进一步压迫处置器。 pipeline进入stalled形态就可以切到其它超线程上
举个例子,假设一个线程运转环节中,肯定要等到一些数据加载到缓存中以后才干继续口头,此时CPU就可以切换到另一个线程,去口头其余指令,而不用去处于闲暇形态,期待以后线程的数据加载终了。 通常,一个传统的处置器在线程之间切换,或许要求几万个时钟周期。而一个具备HT超线程技术的处置器只要要1个时钟周期。因此就大大减小了线程之间切换的老本,从而最大限制地让处置器满负荷运转。
超线程(Hyper-Threading)物理成功 :在CPU外部参与寄存器等配件设备,然而ALU、译码器等关键单元还是共享。在一个物理CPU外围外部,会有双份的PC寄存器、指令寄存器乃至条件码寄存器。超线程的目的,是在一个线程A的指令,在流水线里进度的时刻,让另外一个线程去口头指令。由于这个时刻,CPU的译码器和ALU就空进去了,那么另外一个线程B,就可以拿来干自己要求的事情。这个线程B可没有关于线程A外面指令的关联和依赖。
CPU超线程设计环节中会引入5%的配件,然而有30%的优化(阅历值,场景不一样成果不一样),这是引入超线程的实践基础。假设是一个core4个HT的话优化会是50%
假设physicalid和coreid都一样的话,说明这两个core实践是一个物理core,其中一个是HT。
physicalid对应socket,也就是物理上购置到的一块CPU;coreid对应着每个物理CPU外面的一个物理core,同一个phyiscalid下coreid一样说明开了HT
IPC和一个core上运转多少个进程没有相关。实践测试将两个运转nop指令的进程绑定到一个core上,IPC不变,由于IPC就是从core外面取到的,不针对详细进程。然而假设是这两个进程绑定到一个物理core以及对应的超线程core上那么IPC就会减半。假设程序是IObound(比如要求频繁读写内存)首先IPC远远低于实践值4的,这个时刻超线程同时上班的话IPC基天性翻倍
对应的CPU经常使用率,两个进程的CPU经常使用率是200%,实践产出IPC是2.1+1.64=3.75,比单个进程的IPC为3.92小多了。而单个进程CPU经常使用率才100%
以上测试CPU为Intel(R)Xeon(R)Platinum8260CPU@2.40GHz(Thread(s)percore:2)
在Skylake的架构中,将pause由10个时钟周期参与到了140个时钟周期。重要用在spinlock当中由于spinloop多线程竞争差生的内存乱序而惹起的性能降低。pause的时钟周期高过了绝大少数的指令cpucycles,那么当咱们应用perftop统计cpu性能的时刻,pause会有什么影响呢?咱们可以应用一段小程序来测试一下.
测试机器:CPU:Intel(R)Xeon(R)Platinum8163CPU@2.50GHz*2,共96个超线程
案例:
对如上两个pause指令以及一个count++(addq),启动perftop:
可以看到第一个pasue在perftop中cycles为0,第二个为46.85%,另外一个addq也有48.83%,基本可以猜想perftop在这里数据都往后挪了一个。
疑问总结: 咱们知道perftop是经过读取PMU的PC寄存器来失掉以后口头的指令进而依据汇编的symbol消息取得是口头的哪条指令。所以看起来CPU在口头pause指令的时刻,从PMU中看到的PC值指向到了下一条指令,进而造成咱们看到的这个现象。经过查阅《Intel®64andIA-32ArchitecturesOptimizationReferenceManual》目前还不可得悉这是CPU的一个设计毛病还是PMU的一个bug(要求对pause指令做不凡处置)。 不论怎样,这个试验证实了咱们统计spinlock的CPU占比还是准确的,不会由于pause指令造成PMU采样出错造成统计消息的全体失真。只是关于指令级的CPU统计,咱们能确定的就是它把pause的口头cycles数统计到了下一条指令。
补充说明: 经过测试,非skylakeCPU也雷同存在perftop会把pause(口头数cycles是10)的口头cycles数统计到下一条指令的疑问,看来这是X86架构都存在的疑问。
调用perfrecord采样几秒钟,普通要求加-g参数,也就是call-graph,还要求抓取函数的调用相关。在多核的机器上,还要记得加上-a参数,保障失掉一切CPUCore上的函数运转状况。至于采样数据的多少,在解说perf概念的时刻说过,咱们可以用-c或许-F参数来管理。
8307/08/1913:56:26sudoperfrecord-ag-p47598407/08/1913:56:50ls/tmp/8507/08/1913:57:06history|tail-168607/08/1913:57:20sudochmod777perf.data8707/08/1913:57:33perfscript>out.perf8807/08/1913:59:24~/tools/FlameGraph-master/./stackcollapse-perf.pl~/out.perf>out.folded8907/08/1914:01:01~/tools/FlameGraph-master/flamegraph.plout.folded>kernel-perf.svg9007/08/1914:01:07ls-lh9107/08/1914:03:33history$sudoperfrecord-F99-a-g--sleep60//-F99指采样每秒钟做99次
口头这个命令将生成一个perf.data文件:
口头sudoperfreport-n可以生成报告的预览。口头sudoperfreport-n--stdio可以生成一个详细的报告。口头sudoperfscript可以dump出perf.data的内容。
#折叠调用栈$FlameGraph/stackcollapse-perf.plout.perf>out.folded#生成火焰图$FlameGraph/flamegraph.plout.folded>out.svg
在ECS会采集不到cycles等,cpu-clock、page-faults都是内核中的软事情,cycles/instructions得采集cpu的PMU数据,ECS采集不到这些PMU数据。
从4.2kernel开局,perf允许perfc2c(cache2cahce)来监控cache_line的伪共享
CPU的制作和概念
CPU性能和CacheLine
PerfIPC以及CPU性能
Intel、海光、鲲鹏920、飞扬2500CPU性能对比
飞扬ARM芯片(FT2500)的性能测试
十年后数据库还是不敢拥抱NUMA?
一次性海光物理机资源竞争压测的记载
IntelPAUSE指令变动是如何影响自旋锁以及MySQL的性能的
perf详解
CPU体系结构
震惊,用了这么多年的CPU应用率,其实是错的cpu占用不代表在做事情,或许是stalled,也就是流水线卡顿,然而cpu占用了,实践没事情做。
CPUUtilizationisWrong
哪些因素会影响CPU的性能表现?哪些因素会影响CPU的性能表现?随着计算机技术的发展,CPU(中央处理器)的性能越来越重要。 无论是进行大规模数据处理还是运行复杂的游戏,CPU的性能直接影响计算机的运行速度和效率。 那么,哪些因素会影响CPU的性能表现呢?首先,CPU的主频是影响性能的关键因素之一。 主频指的是CPU时钟频率,可以理解为CPU进行一次运算所需要的时间。 主频越高,CPU的性能表现就越好。 例如,一个3.0GHz的CPU比一个1.8GHz的CPU运行同样任务的速度更快。 然而,主频并不是唯一的关键因素。 其次,CPU的核心数量也会影响性能表现。 现在大多数CPU都是多核处理器,即拥有多个CPU核心。 这意味着CPU可以同时处理多个任务,从而提升计算机的运行速度。 一个拥有4个核心的CPU比一个拥有2个核心的CPU性能更好。 除了主频和核心数量,还有其他因素会影响CPU的性能表现。 例如,缓存大小也会对CPU性能有影响。 缓存是CPU中用于存储临时数据的小容量存储器,它可以缓解CPU和其他硬件设备之间速度不匹配的问题。 缓存越大,CPU的性能表现就越好。 最后,与CPU相关的硬件设备也会影响CPU的性能表现。 例如,内存和硬盘都会影响CPU的性能表现。 内存越大,计算机就越能快速地处理大量数据。 硬盘的速度和容量也会影响CPU的性能表现,因为CPU需要从硬盘中读取数据才能进行处理。 综上所述,CPU的性能表现受多种因素的影响,包括主频、核心数量、缓存大小和硬件设备等。 在使用计算机时,了解这些因素并选择适合自己需求的CPU和硬件设备,可以提高计算机的运行速度和效率。
CPU的性能和速度取决于时钟频率(一般以赫兹或千兆赫兹计算,即hz与Ghz)和每周期可处理的指令(IPC),两者合并起来就是每秒可处理的指令(IPS)。
IPS值代表了CPU在几种人工指令序列下“高峰期”的运行率,指示和应用。而现实中CPU组成的混合指令和应用,可能需要比IPS值显示的,用更长的时间来完成。而内存层次结构的性能也大大影响中央处理器的性能。
通常工程师便用各种已标准化的测试去测试CPU的性能,已标准化的测试通常被称为“基准”(Benchmarks)。如SPECint,此软仵试图模拟现实中的环境。测量各常用的应用程序,试图得出现实中CPU的绩效。
提高电脑的处理性能,亦使用多核心处理器。原理基本上是一个集成电路插入两个以上的个别处理器(意义上称为核心)。在理想的情况下,双核心处理器性能将是宏内核处理器的两倍。
然而,在现实中,因不完善的软件算法,多核心处理器性能增益远远低于理论,增益只有50%左右。但增加核心数量的处理器,依然可增加一台计算机可以处理的工作量。
这意味着该处理器可以处理大量的不同步的指令和事件,可分担第一核心不堪重负的工作。有时,第二核心将和相邻核心同时处理相同的任务,以防止崩溃。
扩展资料:
中央处理器操作原理
CPU的主要运作原理,不论其外观,都是执行储存于被称为程序里的一系列指令。在此讨论的是遵循普遍的冯·诺伊曼结构(von Neumann architecture)设计的设备。程序以一系列数字储存在计算机存储器中。差不多所有的冯·诺伊曼CPU的运作原理可分为四个阶段:提取、解码、执行和写回。
第一阶段,提取,从程序内存中检索指令(为数值或一系列数值)。由程序计数器指定程序存储器的位置,程序计数器保存供识别目前程序位置的数值。
换言之,程序计数器记录了CPU在目前程序里的踪迹。提取指令之后,PC根据指令式长度增加存储器单元。指令的提取常常必须从相对较慢的存储器查找,导致CPU等候指令的送入。这个问题主要被论及在现代处理器的缓存和流水线架构(见下)。
CPU根据从存储器提取到的指令来决定其执行行为。在解码阶段,指令被拆解为有意义的片段。根据CPU的指令集架构(ISA)定义将数值解译为指令。
一部分的指令数值为运算码,其指示要进行哪些运算。其它的数值通常供给指令必要的信息,诸如一个加法运算的运算目标。这样的运算目标也许提供一个常数值(即立即值),或是一个空间的寻址值:寄存器或存储器地址,以寻址模式决定。
在旧的设计中,CPU里的指令解码部分是无法改变的硬体设备。不过在众多抽象且复杂的CPU和ISA中,一个微程序时常用来帮助转换指令为各种形态的讯号。这些微程序在已成品的CPU中往往可以重写,方便变更解码指令。
在提取和解码阶段之后,接着进入执行阶段。该阶段中,连接到各种能够进行所需运算的CPU部件。例如,要求一个加法运算,算术逻辑单元将会连接到一组输入和一组输出。输入提供了要相加的数值,而且在输出将含有总和结果。
ALU内含电路系统,以于输出端完成简单的普通运算和逻辑运算(比如加法和位操作)。如果加法运算产生一个对该CPU处理而言过大的结果,在标志寄存器里,溢出标志可能会被设置(参见以下的数值精度探讨)。
最终阶段,写回,以一定格式将执行阶段的结果简单的写回。运算结果经常被写进CPU内部的寄存器,以供随后指令快速访问。在其它案例中,运算结果可能写进速度较慢,如容量较大且较便宜的主存。某些类型的指令会操作程序计数器,而不直接产生结果资料。
这些一般称作“跳转”并在程序中带来循环行为、条件性执行(透过条件跳转)和函数[jumps]。许多指令也会改变标志寄存器的状态比特。这些标志可用来影响程序行为,缘由于它们时常显出各种运算结果。
例如,以一个“比较”指令判断两个值的大小,根据比较结果在标志寄存器上设置一个数值。这个标志可借由随后的跳转指令来决定程序动向。
在执行指令并写回结果资料之后,程序计数器的值会递增,反复整个过程,下一个指令周期正常的提取下一个顺序指令。
如果完成的是跳转指令,程序计数器将会修改成跳转到的指令地址,且程序继续正常执行。许多复杂的CPU可以一次提取多个指令、解码,并且同时执行。这个部分一般涉及“经典RISC流水线”,那些实际上是在众多使用简单CPU的电子设备中快速普及(常称为微控制器)。
古希腊数学家毕达哥拉斯说,万物皆数学。而数学的精髓是公式。衡量CPU性能的同样有一个公式:CPU性能公式。我写在纸上了,拍成图片如下:
图片中的CPU性能公式看着挺吓人,概括后其实就是一句话:要提高CPU的性能,就要减少程序执行的时间。换句话说就是,提高CPU执行程序的效率。换成通俗易懂的话就是,员工(CPU)干同样的活(执行程序),花的时间越少,则工作效率越高,老板越高兴。反之,工作效率越低,老板会把这类员工优化掉。从CPU性能公式可以看出,要让CPU提高程序的执行效率(提高处理器性能),需要从三个方面入手:减少程序的指令数;减少指令的执行周期数;减少时钟周期时间(每周期的时间);而要把这三方面做圆满了,实际就等于重新设计一款CPU,用行话说就是采用新的CPU架构。换句话说,架构才是决定CPU性能的关键,一款CPU性能是否强大,和它是否采用了漂亮的新架构有决定关系。至于频率和工艺制程,则是影响CPU性能的次要因素。19年前的2000年,英特尔发布了奔腾4,运行频率达到4GHz,超过现今大多数CPU。
奔腾4采用NetBurst架构,英特尔号称它能飙到10GHz,但由于NetBurst架构设计翻车,频率是飙上去了,功耗也线性提升,性能(整数运算和浮点运算)却被旧的P6架构吊打,后来搞得英特尔CEO贝瑞特为此当众单膝着地致歉。
奔腾4的教训说明架构对提升CPU性能远比频率重要。由于工艺制程影响CPU运行频率,所以三者对CPU性能影响,按重要程度从重到轻排列:架构>工艺制程>频率。架构对CPU性能的巨大影响,可能被很多人忽视,因为大多数人认为,工艺制程挤牙膏会导致CPU性能提升不明显。其实,架构挤牙膏才是妨碍CPU性能提升的元凶。同样请出CPU界老大英特尔,其2013年发布的i5-4300U,到2017年的i5-7300U,一共有4代CPU,工艺制程也从22nm节点上升到14nm节点,然而实际性能增长曲线就是一条平坦的线条(见下图黄色线条),一点不性感。
低压版i5的性能之所以没有随制程同步提升,主要原因就是,从i5-4300U的Haswell架构到2017年i5-7300U的Kaby Lake架构都是小修小补,不客气地说就是,英特尔在架构上挤牙膏了。CPU性能强不强,就看架构猛不猛。就这么简单。原创回答,搬运必究。
标签: 中央处置器、 性能优化、 ipc、 CPU、本文地址: https://yihaiquanyi.com/article/718378f27cbb308e1c2d.html
上一篇:深度揭秘OceanBase事务引擎的独特特性和应...