新闻详情

新闻详情

首页 / 资讯中心 / 详情

性能之巅 导读(六):CPU

发布时间:2026/9/28 21:25:18来源:尧图网络
性能之巅 导读(六):CPU
本文是《性能之巅》Systems Performance第 2 版第 6 章的导读。本书是系统性能领域的经典本系列逐章导读把书的核心概念讲清楚。工厂上一章讲了重点企业——应用程序。现在该进工厂了。CPU 就是城市的工厂——它把指令加工成结果驱动整座城市运转。但工厂也是最容易被误诊的地方工厂忙不一定有问题工厂闲也可能藏着大麻烦。这一章我们分两部分讲先搞清楚工厂是怎么运转的理论再看怎么给工厂做检查实操。一、工厂是怎么运转的从一颗芯片说起你有没有想过你电脑里那块指甲盖大小的芯片到底是怎么干活的想象你走进一座工厂。这座工厂不大但里面有几间独立车间。每间车间都能独立接活、独立干活。你看到的8 核 16 线程说的就是一个物理芯片上有 8 间车间每间车间里挤了 2 个工人。但等等——一间车间里坐两个工人他们不打架吗会。但工厂的设计者算过一笔账工人大部分时间其实在等物料。物料从仓库送过来可能要等几百个时钟周期。与其让工人干坐着不如趁他等物料的时候让他去操作另一台机器。这就是 Intel 的Hyper-Threading超线程技术。所以操作系统看到的是 16 个工位但真正干活的是 8 间车间。两个工人共享同一间车间的资源——如果两个人同时都在做重活就会互相抢工具、抢物料架反而拖慢彼此。所以超线程带来的性能提升不是 2 倍通常只有1.2 到 1.3 倍。那问题来了工人具体是怎么干活的工人是怎么干活的工人干活靠的是指令。你可以把一条指令想象成一张加工单——上面写着把这两个数加起来“从仓库取一个物料”“把结果放到成品区”。一张加工单的执行分五步取指 → 译码 → 执行 → 访存 → 写回取指工人去公告板拿下一张加工单译码看懂这张单子要干什么执行真正动手加工访存如果加工需要物料去物料架取写回把加工好的成品放到指定位置每一步至少花一个时钟周期。其中访存最慢——如果物料不在手边可能得等几十甚至几百个周期。但工人不是一张一张单子傻等的。现代工厂有流水线——第一条指令在执行的时候第二条在译码第三条在取指同时进行。理想情况下每个时钟周期就能完成一条指令。但流水线最怕两件事第一分支预测失败。加工单上可能写着如果物料是红色的就做 A否则做 B。工人在译码阶段就得猜——到底该做 A 还是 B猜对了流水线继续猜错了整条流水线清空重来前面做的全白费。第二缓存未命中。工人执行到访存这一步发现物料不在手边的架子上得去车间仓库找车间仓库也没有得去中央仓库中央仓库还没有得去外面调货——每多一层就多等几十到几百个周期。这就是为什么缓存如此重要。物料架为什么缓存这么重要工人旁边有几层物料架越近越快越远越慢层级比喻大小访问延迟L1手边的小架子几十 KB1–3 个周期L2车间里的工具柜几百 KB 到几 MB10–20 个周期L3车间共用的仓库几十 MB30–50 个周期主内存中央仓库几十 GB100–300 个周期磁盘外部仓库TB 级慢几个数量级你可能会想几百个周期而已能有多慢让我们算一笔账。假设 CPU 主频是 3 GHz一个周期约 0.33 纳秒。如果访问 L1 需要 3 个周期那是 1 纳秒。如果访问主内存需要 200 个周期那是66 纳秒——差了 66 倍。更直观的对比如果 L1 访问相当于你伸手拿桌上的水杯1 秒那主内存访问相当于你走到楼下便利店买瓶水66 秒。而磁盘访问相当于你开车去另一个城市买水几小时。最要命的是缓存命中率从 99% 掉到 90%性能可能腰斩。因为那 1% 的没命中要去访问慢速内存而 CPU 在等的时候什么都干不了。那工厂怎么知道自己忙不忙效率高不高呢工厂的效率指标评价工厂不能只看忙不忙要看产出效率。第一个指标是IPC每周期指令数——平均每个时钟周期加工了多少条指令。IPC 高比如 1.5工人在高效加工IPC 低比如 0.2工人大部分时间在等物料第二个指标是利用率——工厂有多少时间在运转。第三个指标是饱和度——多少工人在排队等上工。你可能会觉得利用率越高越好恰恰相反。一个反直觉的事实是利用率 100% 但 IPC 只有 0.2这是浪费——工人在忙着等物料。反过来利用率 50% 但 IPC 1.5这是好事——工厂一半时间在高效加工另一半时间留给突发任务。这就像一家餐厅如果桌子永远坐满利用率 100%但每桌客人都在等菜IPC 低那这家餐厅的效率其实很差。如果一半桌子空着利用率 50%但每桌客人来了就上菜IPC 高那才是好餐厅。那如果多个企业都要用工厂谁先上工呢工厂的调度当多个企业都要用工厂时调度器决定谁先上工。工作负载分两类CPU 密集型计算型任务——科学计算、机器学习。它们一旦上工就一直占用机器。I/O 密集型等 I/O 的任务——Web 服务器、文件服务器。它们干一小会儿就去等 I/O 了。调度策略是优先让 I/O 密集型任务先跑。因为它们跑一小会儿就去等 I/O 了能让出机器给别的任务。而 CPU 密集型任务可以等——它们不急。现代 Linux 默认用CFS完全公平调度器——按虚拟运行时间排序谁运行时间少谁优先。还有RT实时调度优先级最高但风险是如果 RT 任务进入死循环整个工厂会卡死。二、怎么给工厂做检查理论讲完了现在看实操。工厂出问题时你怎么查uptime看一眼负载$uptime9:04pm up268day(s),10:16,2users, load average:7.76,8.32,8.60三个数字分别是 1 分钟、5 分钟、15 分钟的平均负载。比较三个数字能看出趋势1 分钟 15 分钟负载在上升——问题可能加剧1 分钟 15 分钟负载在下降——问题可能过去了三个差不多负载平稳注意Linux 的负载平均值包含等待 I/O 的线程TASK_UNINTERRUPTIBLE不是纯 CPU 负载。这是它和 Solaris 的一个区别——看到高负载时要确认到底是 CPU 还是 I/O。类比uptime 像看一眼候工区有多少工人——快速判断忙不忙。vmstat全厂仪表盘$vmstat1procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu----- r b swpdfreebuff cache si so bi boincs us syidwa st150045173270588866628001104338219700150045096870588866628000612106429697228000150045066070588866632000096129327228000关键列r运行队列长度——大于车间数就饱和us用户态工厂时间sy内核态工厂时间id空闲wa等 I/O——工厂空闲但等 I/Ost被偷走的时间——虚拟机专属类比vmstat 像工厂仪表盘的总览屏——流水线速度、产量、等料时间、设备利用率一眼全看到。mpstat逐个车间看$ mpstat-PALL1CPU %usr %nice %sys %iowait %irq %soft %steal %guest %idle all32.160.0061.810.000.000.000.000.006.03032.000.0064.000.000.000.000.000.004.00132.320.0059.600.000.000.000.000.008.08用途发现单车间热点——一个车间 100%其他车间闲着说明线程扩展性有问题。%steal是虚拟机专属宿主把 CPU 时间偷去给了别的租户。类比mpstat 像分别看每个车间的运转情况——发现具体哪一块出问题。sar看历史sar前面章节介绍过关键是它能看历史数据。CPU 相关选项-u工厂使用率-P ALL每个车间-q运行队列$ sar-u13Linux5.3.0(bgregg)02/01/20 _x86_64_(2CPU)18:00:32 CPU %user %nice %system %iowait %steal %idle18:00:33 all32.160.0061.810.000.006.03类比sar 像以前的运营报告——能看三天前流水线速度多少。ps看每个企业$psauxUSERPID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root10.00.0237721948? Ss20120:04 /sbin/init... web1172196.50.163811652108pts/1 Rl 01:373:33nodeproxy.js关键列%CPU平均工厂使用率进程生命周期内的平均TIME累计工厂时间注意%CPU是平均值不是当前值。要看当前值用top。类比ps 像看每个企业的生产记录——这个企业总共用了多少工厂资源。top实时监控屏$toptop- 01:38:11 up63days,1:17,2users, load average:1.57,1.81,1.77Tasks:256total,2running,254sleeping,0stopped,0zombie Cpu(s):2.0%us,3.6%sy,0.0%ni,94.2%id,0.0%wa,0.0%hi,0.2%si,0.0%st PIDUSERPR NI VIRT RES SHR S %CPU %MEM TIME COMMAND11721web200623m 50m4984R930.10:59.50node用途实时找最忙的企业。注意top自己会消耗工厂资源——它要读所有进程的/proc文件。如果top自己出现在 CPU 消耗榜上说明系统进程多、开销大。类比top 像实时监控屏——谁在满负荷、谁在偷懒一目了然。pidstat按进程拆 CPU 时间$ pidstat1PID %usr %system %guest %CPU CPU Command781597.032.970.00100.0011gzip78140.001.980.001.983tartop只能告诉你哪个进程忙pidstat把时间拆成用户态和内核态%usr用户态时间%system内核态时间%CPU总共占用用途一个gzip进程 97% 用户态时间——说明它在做压缩计算一个tar进程大部分是内核态——说明它在做 I/O。类比pidstat 像把每个企业的工时拆成实际加工时间和办手续时间。time / ptime给单个命令计时$timecksumubuntu-19.10-live-server-amd64.iso1044945083883949568ubuntu-19.10-live-server-amd64.iso real 0m5.590s user 0m2.776s sys 0m0.359s三个时间real真实经过的时间墙钟时间user用户态 CPU 时间sys内核态 CPU 时间如果real远大于user sys说明进程在等 I/O——比如第一次运行时文件没缓存。类比time 像给一个具体任务掐表——总共花了多久其中真正干活多久办手续多久。turbostat / showboost看 CPU 频率CPU 并不是一直跑在最高频率——它有P-state性能状态和C-state电源状态。频率会动态调整省电时降频负载高时升频Turbo Boost。# turbostatCore CPU Avg_MHz Busy% Bzy_MHz TSC_MHz - -972.7036092112001283.4437002112用途确认 CPU 是否在跑最高频率。如果发现频率很低可能 BIOS 里节能设置把频率压住了性能就不是 CPU 的错是配置的错。类比turbostat 像看工厂机器有没有开到最高档——档位没开满再好的机器也发挥不出来。pmcarch / tlbstat看微架构效率这两个工具是 PMC性能监控计数器的封装能看到 CPU 底层的效率细节。# pmcarchK_CYCLES K_INSTR IPC BR_RETIRED BR_MISPRED BMR% LLCREF LLCMISS LLC%96163187871663130.91197309949256791872993.4465659745417431379973.45关键列IPC每周期指令数——效率指标BMR%分支预测失败率LLC%最后一级缓存命中率# tlbstat -C0 1K_CYCLES K_INSTR IPC DTLB_WALKS ITLB_WALKS K_DTLBCYC DTLB% ITLB%28757932760510.10897094966586230278791327.4022.63DTLB%和ITLB%是地址转换占用 CPU 周期的比例。如果这个数字很高说明 TLB地址转换缓存没命中每次都要走慢路径。注意这两个工具依赖具体 CPU 型号不一定在所有环境都能用。但思路通用用 PMC 看 CPU 底层效率判断瓶颈是计算还是访存。类比pmcarch/tlbstat 像给工厂机器做微观体检——不是看它忙不忙是看它内部零件有没有卡顿。perf工厂分析的主力perf是 Linux 官方性能工具也是 CPU 分析的首选工具。它能做三件大事采样、计数、追踪。第一CPU 剖析采样——找出 CPU 时间花在哪# 全系统采样栈99 Hz30 秒perf record-F99-a-g--sleep30perf report--stdio输出能看到每个函数的占比比top更深入——top只能告诉你哪个进程忙perf能告诉你进程里哪个函数忙。生成火焰图perf script--headerout.stacksgitclone https://github.com/brendangregg/FlameGraphcdFlameGraph ./stackcollapse-perf.pl../out.stacks|./flamegraph.pl--hashout.svg第二IPC 统计——判断是忙但低效还是忙且高效$ perfstatgzipwords209,911,358 cycles288,321,441 instructions# 1.37 insn per cycleIPC 1.37 说明效率不错。如果 IPC 0.2说明工人在等物料——大概率是内存瓶颈。第三调度延迟——看线程等 CPU 等了多久# 记录调度事件 10 秒perf sched record --sleep10perf sched latency输出会显示每个任务的平均调度延迟和最大调度延迟。注意perf sched record数据量大——10 秒可能产生 125 MB 的perf.data因为调度事件非常频繁。生产环境慎用。类比perf 像工厂的全能侦探工具——既能拍 X 光剖析又能测内耗调度延迟又能算效率IPC。profileperf 的轻量替代profile是 BCC 工具和perf record类似但更轻量——它在内核里聚合栈信息只把唯一栈和计数传给用户态不用先写perf.data再处理。# profile 10Sampling at49Hertz of all threads by user kernel stackfor10secs. finish_task_switch __sched_text_start schedule... - mysqld(5187)151用途快速看 CPU 栈分布。输出最后一行是进程名、PID、采样次数。生成火焰图profile-af10out.stacks ./flamegraph.pl--hashout.stacksout.svg类比profile 像轻便版 X 光机——不用搬大设备随时拍一张。cpudist每次上工多久# cpudist 10 1usecs:count distribution0-1:3618650|****************************************|2-3:2704935|*****************************|4-7:421179|****|8-15:99416|*|用途看线程每次在 CPU 上待多久。如果线程跑得又短又碎大量 10 μs说明工厂竞争严重——线程频繁被切出去缓存永远不热。注意这个工具需要 BCCbcc-tools包。类比cpudist 像看每个工人每次上工能干多久——10 μs 就被叫走说明车间太挤了。runqlat线程等 CPU 等了多久# runqlat 10 1usecs:count distribution0-1:9017|*****2-3:7188|****...65536-131071:88|-- 这些是长等的线程用途看线程从可运行到真正上工等了多久。runqlat比cpudist更有意义——因为调度延迟是线程真正感受到的等待。如果大量线程等了几十毫秒才上工说明 CPU 严重过载。注意runqlat采样频繁每次上下文切换生产环境要评估开销。轻量替代是runqlen定时采样。类比runqlat 像看工人在候工区等了多久才被叫上工。runqlen运行队列有多长# runqlen 10 1runqlen:count distribution0:1824|****************************************|1:158|***用途定时采样运行队列长度开销极低。比runqlat更温和——runqlat每次上下文切换都记录runqlen只是每秒采样几次。适合长期监控。类比runqlen 像定时看一眼候工区排了多长的队。softirqs / hardirqs中断开销中断是硬件和内核之间的插话——网卡收到包、磁盘完成 I/O都会打断 CPU。# softirqs 10 1SOFTIRQ TOTAL_usecs net_tx9rcu751sched3431timer5542tasklet11368net_rx12225# hardirqs 10 1HARDIRQ TOTAL_usecs nvme0q235ens5-Tx-Rx-05922用途看中断把 CPU 时间吃掉了多少。如果net_rx或ens5-Tx-Rx-0很高说明网络流量大如果nvme0q1很高说明磁盘 I/O 频繁。注意这些中断开销不会出现在普通 CPU 剖析里——因为中断处理不可被采样器打断所以要用专门的工具看。类比softirqs/hardirqs 像统计工厂被临时插单打断了多久——这些时间看不见但真实存在。bpftrace自定义追踪前面讲的都是现成工具bpftrace是让你自己写工具。比如统计所有内核函数调用次数bpftrace-ekprobe:attach* { [probe] count(); }比如记录vfs_read()耗时分布bpftrace-ek:vfs_read { ts[tid] nsecs; } kr:vfs_read /ts[tid]/ { hist(nsecs - ts[tid]); delete(ts[tid]); }用途现成工具不够用时用bpftrace写一个。CPU 相关的常见场景统计调度函数、追踪特定内核路径、测自定义延迟。类比bpftrace 像工厂里可以自己组装检测设备——想要什么指标自己搭一个。三、可视化与调优可视化CPU 分析最有用的是火焰图——它把成千上万条栈样本压缩成一张图宽度代表时间占比一眼看出哪个函数最耗 CPU。perf和profile都能生成。另一个是利用率热图——把每个 CPU 的利用率按时间画成热图能看出负载均衡问题。调优CPU 调优主要是三件事。第一优先级。nice调静态优先级chrt调调度策略。$nice-n19command# 低优先级运行$ chrt-bcommand# 批处理调度第二CPU 绑定。把进程绑到特定 CPU提高缓存命中率。$ taskset-pc7-1010790# PID 10790 只跑在 CPU 7-10第三资源控制。用 cgroups 限制 CPU 配额或者用 exclusive cpusets 给进程独占 CPU。# 给进程组限制 CPU 带宽echo50000/sys/fs/cgroup/cpu/mygroup/cpu.cfs_quota_us注意CPU 调优最大的赢往往不是调参数而是消除不必要的工作——用剖析找到最热的代码路径优化它。四、总结不要看 CPU 忙不忙要看效率高不高——利用率、IPC、缓存命中率一起看不要让 CPU 空转等内存——不是等 I/O是等物料缓存决定性能上限——缓存命中率高工厂就快缓存命中率低工厂就等。调度延迟往往比工厂占用更值得关注——用runqlat看调度延迟用cpudist看每次工作时长。如果线程跑得又短又碎说明工厂竞争严重。多核该用就用但别盲目堆——超线程、锁争抢都可能让多核变成负担下一章讲内存——也就是办公桌。工厂讲完了接下来看工人旁边的办公桌。办公桌不够用工厂也干不了活。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

基于PaddleOCR的车牌识别算法:从检测到识别的全流程实战与优化 2026/9/28 22:21:08

基于PaddleOCR的车牌识别算法:从检测到识别的全流程实战与优化

简介:本资源面向计算机视觉初学者与进阶开发者,提供一套基于PaddleOCR的车牌识别完整项目源码,帮助读者从零搭建可运行的车牌检测与识别系统,解决车牌定位、字符识别及模型部署等实际问题。压缩包共416个文件,约37MB&a…

阅读更多 →
Python深度学习人脸识别系统毕业设计:从CNN选型到答辩演示全链路 2026/9/28 22:21:08

Python深度学习人脸识别系统毕业设计:从CNN选型到答辩演示全链路

简介:这份资源面向高校学生与深度学习入门者,提供一套基于Python的人脸识别系统完整毕业设计实现,涵盖代码、模型与文档说明,可用于毕业设计、课程设计或期末大作业。项目采用深度学习方案,涉及FER2013、CK、JAFFE等公…

阅读更多 →
Python视频剪辑-Moviepy图文处理ImageClip 2026/9/28 22:21:02

Python视频剪辑-Moviepy图文处理ImageClip

在视频编辑和多媒体制作中,静态图像和文本的动态展示成为增强视觉效果的关键手段。ImageClip 和 TextClip 作为 moviepy 中的强大工具,提供了将静态图片和文字转化为视频剪辑的便捷方式。无论是为视频插入图片或文字,还是为图片添加透明效果和动画过渡,这些功能都极大地丰富…

阅读更多 →
小米开源MiMo-V2.6:Pro/Flash双版本与API部署实战解析 2026/9/28 22:21:02

小米开源MiMo-V2.6:Pro/Flash双版本与API部署实战解析

1. 全系列发布:MiMo-V2.6 的双版本策略小米把 MiMo-V2.6 做成 Pro 和 Flash 两个版本一起开源,这个动作在圈内其实比模型本身更有看点。国内大模型开源生态里,同一代模型一次性放出完整版和轻量版的情况不算多,大多数厂商习惯先发…

阅读更多 →
山东靠谱的电商财税合规专业机构客户口碑力荐 2026/9/28 22:20:55

山东靠谱的电商财税合规专业机构客户口碑力荐

做电商的老板,多少都藏着几本糊涂账。多店铺开着,流水从支付宝、微信转到私卡,拿货没有进项票,报税只敢报开票收入,平台数据和申报对不上,夜里睡觉都担心金税四期的大数据预警。普通代账公司看不懂电商后台…

阅读更多 →
MiMo-V2.6开源双版本大模型:API平价背后的本地部署与模型选型 2026/9/28 22:20:55

MiMo-V2.6开源双版本大模型:API平价背后的本地部署与模型选型

近两年开源大模型的迭代速度,用一个词来形容就是“疯狂”。各大厂商从过去单纯卷参数、卷跑分,逐渐转向卷开源生态、卷API性价比。小米这次放出的 MiMo-V2.6 系列,最让我留意的不是“Pro 与 Flash 双版本”这个产品矩阵本身,而是那…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉