CPU · 温度

CPU 温度是怎么 读出来 的

它不是一支温度计测出的绝对温度,而是一个数字传感器报出的“离关断点还有多少度”。所以 TjMax 读错,所有温度会整体平移;绑定核心失败,八个核会显示同一个数。

更新于 2026-11-02 · Windows 10 / 11 · Intel MSR(DTS / TjMax / 撞墙位)

一句话结论:CPU 内部的数字温度传感器(DTS)并不直接给出“现在是 62℃”,它给出的是“离 TjMax 还差 38 度”。真实温度 = TjMax − 偏移。所以任何一个软件要显示温度,都必须先知道这颗 CPU 的 TjMax;TjMax 取错,整排温度一起错,而且错得很整齐。

一、温度不是温度:DTS 报的是偏移量

这个设计是有原因的。DTS 关心的是“还能不能继续跑”而不是“现在多少度”——它只需要知道热点离降频点还有多远。于是寄存器里放的是一个 7 位无符号偏移(0 到 127),单位是摄氏度,数值越大表示越凉快。

真实温度 = TjMax − 偏移

举例:TjMax 是 100℃,偏移读到 38,温度就是 62℃。这条公式看起来简单,但它带来一个副作用:温度的可信度完全依赖 TjMax。如果软件读不到 TjMax,退回一个默认值(常见是 100),而实际这颗芯片的 TjMax 是 95 或 105,那么所有核心温度会整体偏 5 度——不高不低,看起来完全正常,你很难发现。

二、三个寄存器:每核、封装、TjMax

MSR名称内容
0x19CIA32_THERM_STATUS每个逻辑核自己的 DTS 偏移
0x1B1IA32_PACKAGE_THERM_STATUS封装级的 DTS 偏移
0x1A2IA32_TEMPERATURE_TARGETTjMax,单位摄氏度

三个寄存器的读法都要过内核(一条 RDMSR 指令),用户态程序做不了,所以监测软件通常自带一个签名驱动,或者用经过验证的第三方驱动。这一点和读主板传感器、读内存 SPD 是同一个前提:没有内核这一层,什么都读不到。

TjMax 的取值还要做一次合理性检查:合法范围大约 0 到 150℃,超出就当没读到。这一步不能省——某些虚拟机和部分工程样品上,这个寄存器会返回 0 或全 1,直接拿来算会得出 −100℃ 或 1000℃ 这种数。

三、为什么八个核显示同一个温度

这是一个很典型、但很少有人查的问题:界面上八个核的温度完全一致,而且跑单核负载时八个一起升。

根因不在传感器,在采样时线程跑在哪个核上。RDMSR 读的是“执行这条指令的那个逻辑处理器”的状态。想读第 3 个核,就必须让采样线程真的在第 3 个核上运行。

常见做法是:设置线程亲和性到目标核,然后“让出一下”再读。问题出在“让出一下”这一步——如果当前没有其它就绪线程,让出并不会真的把线程调度到别的核,它还在原地。于是八次循环全部落在同一个核上,读回同一个值,界面上就成了“八核同温”。

可靠的写法是带验证的迁移:设置亲和性后,反复确认当前处理器编号是否已经等于目标核,不是就让出并短暂睡眠,最多重试若干次;确认落在目标核后才执行 RDMSR,读完恢复原来的掩码。

这类问题的麻烦之处在于:它既不崩溃、也不是读不到,而是读到了一个真实的、但不属于这个核的数字。八核同温的现象又太像“传感器本来就这样”,很难让人怀疑到线程调度上——这也是为什么这个点在不少工具上长期存在却没人发现。

判断方法很简单:跑一个单核压力测试(把负载绑到某一个核)。正常情况只有那一个核明显升温;如果八个核一起升、数值还几乎相同,就是采样没有真正绑核,读到的是同一个核的八次拷贝。

四、核心温度与封装温度差在哪

0x19C 是每个核自己的 DTS,位置在核内的热点附近;0x1B1 是封装级的那个传感器,覆盖整个芯片但不在最热点上。所以同一次读数里,封装温度通常略低于最热的那个核,差 5 到 15 度都算正常。

这条差值有实用价值:

  • 判散热够不够,看最热的核。封装值更“好看”,但它是平均意义的,会掩盖单核热点。
  • 八个核温差很大(比如两核 95℃、六核 70℃)通常是负载分配不均,不是传感器坏了。
  • 封装温度高于所有核心温度,反而要警惕——可能是读取时两者不在同一时刻,也可能是这颗芯片的封装传感器位置特殊。

五、撞墙:温度墙、功耗墙、电流墙

温度只是结果,真正决定性能的是“有没有撞墙”。芯片在同一处状态里为每类限制各留了两个标志:一个是“现在正在撞”,一个是“曾经撞过”。

类型什么意思说明
温度墙核心温度已到 TjMax最直接的降频原因,跑分掉速多半是它
PROCHOT降频信号被拉低主板的供电与温控也会触发,不一定来自 CPU 自己
功耗墙撞到 PL1 / PL2 的功率上限温度不高也可能被限,笔记本尤其常见
电流墙撞到电流上限瞬时大负载时出现
跨域限制其它域给出的限制,俗称 EDP Other多见于笔记本,和厂商设定的策略有关

关键区别在于封装级只报前三类:封装温度墙、封装 PROCHOT、封装的功耗墙。电流墙和跨域限制只存在于每个核自己的状态里。所以“我明明看到撞墙了,软件却说没有”,有时只是查错了地方。

这里有一个流传很广的错:把封装级的“温度墙”标志当成 PROCHOT,把封装的“功耗墙历史位”当成 PROCHOT 历史位。按错的位去解,会得到一个一直亮着的 PROCHOT 告警,同时白白浪费掉一个本来就在读的功耗墙记录。

为什么“曾经撞过”这一类位不能直接用

Log 位是“写 1 清零、写 0 无效”的类型(R/WC0)。它开机会话就已经被置位过,而且如果要清它就必须能写这个 MSR——很多驱动只放行读、不放行写。结果就是:读出来一直是 1,界面上的告警一直亮着,也复位不掉。

更可靠的做法是不去读那个粘滞位,而是自己采样算占比:用较高的频率(例如每秒 20 次)反复读“正在撞”的那一位,一秒内命中多少次就除以总采样次数,得到“这一秒里有多少比例的时间在撞墙”。占比 0.05 和 1.0 是完全不同的两件事,而粘滞位只能告诉你“曾经发生过”。

所以更可靠的选择是不依赖硬件粘滞位,而是用采样统计“正在撞”的那一位出现的时间占比。HwDetect 的温度页取的就是后一条路:撞墙按秒级窗口显示占比,粘滞位只作参考,不直接拿来点亮告警。硬件粘滞位在部分平台上开机就已经是 1(多核处理器上这一类位常常一上电就全部置位),把它并进告警,界面会从第一秒起永久亮着、还清不掉,用户唯一能做的就是忽略它——那这个指示就等于不存在。

顺带一个容易被忽略的细节:Sleep(1) 的含义是“至少 1 毫秒”,实际醒来时刻还受系统定时器分辨率影响,可能明显长于 1 毫秒。所以采样间隔不能想当然——要么临时提高分辨率、用完再恢复,要么干脆不假设间隔,按每次实际经过的时间换算出占比。

六、多少度算高(看余量,不看绝对值)

“多少度正常”这个问题没有统一答案,因为每颗 CPU 的 TjMax 不同。有意义的是离 TjMax 还剩多少度:

状态离 TjMax 的距离怎么看
宽裕15℃ 以上散热有余量,长时间负载也没问题
偏紧5 到 15℃还能用,但风扇已经接近满速;夏季或积灰会进入降频
临界5℃ 以内随时会触发温度墙,性能开始波动
已在降频0(撞墙位置位)不是“有点热”,是已经在损失性能

桌面平台的 TjMax 常见 100℃;笔记本不少型号也是 100℃,但也有更高的。先确认自己这颗的 TjMax,再谈多少度算高:同样是 95℃,在 TjMax=100 的机器上只剩 5 度余量,在 TjMax=105 的机器上还有 10 度。

另外两个常见误判:待机 50℃ 不算问题(受环境温度与风扇曲线影响很大);跑分瞬间冲到 95℃ 然后回落也不算问题(那是短时功耗墙 PL2 在起作用),要看的是持续负载下的稳态温度。

七、怎么验证自己的读数是对的

  1. 看 TjMax。如果软件能显示 TjMax,确认它不是“默认 100”顶上去的。同一个型号不同步进,TjMax 可能不同。HwDetect 的温度页把 TjMax 和每核读数放在同一屏,就是为了让这一步能当场做掉,而不是去别处查表。
  2. 跑单核负载。应该只有一核升温。八核同升、同值,就是绑核失败。
  3. 跑全核负载看稳态。温度先升到某个值后趋于平稳,是正常的;一直缓慢上升不收敛,说明散热已经到极限。
  4. 对一下封装功耗。两台机器比温度之前,先比同一负载下的封装功耗。功耗不同,温度没有可比性。
  5. 看有没有撞墙位。比温度更有意义:温度 95℃ 但没撞墙,和温度 80℃ 却一直在功耗墙,后者性能损失更实际。

相关阅读:主板传感器芯片通道对照 · 硬盘健康度怎么看(SMART) · 怎么看内存 SPD、时序和 XMP

八、常见问题

CPU 温度多少算正常?
看余量,不看绝对值。绝大多数 Intel 桌面型号的 TjMax 是 100℃,持续负载下核心温度在 85℃ 以内算宽裕,接近 95℃ 说明散热余量已经很少,到 100℃ 会开始降频。笔记本的 TjMax 常见 100℃ 也可能是 105℃,同样温度在两者身上余量不同,所以要先确认自己的 TjMax。
为什么每个核心的温度完全一样?
这不正常,多半是读的时候没能真正绑定到目标核心。RDMSR 是每个逻辑处理器各自的状态,如果采样线程没有被迁移到第 N 个核,读到的其实是同一个核的值,于是八次读数是同一个数。判断方法:跑一个单核负载,正常情况应该只有那一个核明显升温。
核心温度和封装温度哪个准?
两者测的不是同一个点。核心温度来自每个核自己的 DTS,封装温度来自封装级的那个传感器。通常封装温度略低于最热的核,因为它不在热点上;两者相差 5 到 15 度都正常。要判断散热够不够,看最热的核,不看封装值。
为什么我的 CPU 温度比同型号的人高 10 度?
三个最常见原因:TjMax 读出来不同(读不到时会退回默认 100,而实际可能是别的值)、散热器与机箱风道不同、以及主板功耗墙设置不同导致实际功耗不一样。先比同一负载下的封装功耗,再比温度,否则比的是两台不同的机器。
待机 50 度算高吗?
不算。待机温度受环境温度、机箱风道和风扇曲线影响很大,夏天 45 到 55 度很常见。真正需要关注的是满载时的稳态温度和到达稳态的速度,而不是空闲时那一个数字。
温度显示 0 或者干脆没有这一项,是什么原因?
读不到时应当留空,而不是显示 0。0 通常意味着两种情况之一:DTS 偏移被读成 0(此时算出来的温度会等于 TjMax),或者该核的读数落在无效区间被判定为不可用。如果软件把无效值渲染成 0 度,看到 0℃ 就该怀疑是读取失败,不是真的 0 度。HwDetect 在这一项上的取舍是宁可整行不出现,也不补一个 0 上去。
为什么 AIDA64 和 HWiNFO 显示的温度差几度?
多数是采样时刻与采样对象不同。两者刷新周期不一样,看到的不是同一瞬间;另外有的软件显示最热核、有的显示封装值、有的做滑动平均。要对比就先固定到同一个量:同一次负载、同一个时刻,都看最热核。
HwDetect CPU 温度
  • 每核温度按核绑定读取,并校验是否真的迁移到了目标核
  • TjMax 从 MSR 实读,读不到才退回默认值,不做静默假设
  • 温度墙 / 功耗墙 / 电流墙按秒级窗口给出占比,不依赖清不掉的粘滞位

温度与撞墙位均为本地读取,需要管理员权限执行 RDMSR。仅支持 Intel 平台,AMD 走各自的接口。