它不是一支温度计测出的绝对温度,而是一个数字传感器报出的“离关断点还有多少度”。所以 TjMax 读错,所有温度会整体平移;绑定核心失败,八个核会显示同一个数。
这个设计是有原因的。DTS 关心的是“还能不能继续跑”而不是“现在多少度”——它只需要知道热点离降频点还有多远。于是寄存器里放的是一个 7 位无符号偏移(0 到 127),单位是摄氏度,数值越大表示越凉快。
真实温度 = TjMax − 偏移
举例:TjMax 是 100℃,偏移读到 38,温度就是 62℃。这条公式看起来简单,但它带来一个副作用:温度的可信度完全依赖 TjMax。如果软件读不到 TjMax,退回一个默认值(常见是 100),而实际这颗芯片的 TjMax 是 95 或 105,那么所有核心温度会整体偏 5 度——不高不低,看起来完全正常,你很难发现。
| MSR | 名称 | 内容 |
|---|---|---|
0x19C | IA32_THERM_STATUS | 每个逻辑核自己的 DTS 偏移 |
0x1B1 | IA32_PACKAGE_THERM_STATUS | 封装级的 DTS 偏移 |
0x1A2 | IA32_TEMPERATURE_TARGET | TjMax,单位摄氏度 |
三个寄存器的读法都要过内核(一条 RDMSR 指令),用户态程序做不了,所以监测软件通常自带一个签名驱动,或者用经过验证的第三方驱动。这一点和读主板传感器、读内存 SPD 是同一个前提:没有内核这一层,什么都读不到。
TjMax 的取值还要做一次合理性检查:合法范围大约 0 到 150℃,超出就当没读到。这一步不能省——某些虚拟机和部分工程样品上,这个寄存器会返回 0 或全 1,直接拿来算会得出 −100℃ 或 1000℃ 这种数。
这是一个很典型、但很少有人查的问题:界面上八个核的温度完全一致,而且跑单核负载时八个一起升。
根因不在传感器,在采样时线程跑在哪个核上。RDMSR 读的是“执行这条指令的那个逻辑处理器”的状态。想读第 3 个核,就必须让采样线程真的在第 3 个核上运行。
常见做法是:设置线程亲和性到目标核,然后“让出一下”再读。问题出在“让出一下”这一步——如果当前没有其它就绪线程,让出并不会真的把线程调度到别的核,它还在原地。于是八次循环全部落在同一个核上,读回同一个值,界面上就成了“八核同温”。
可靠的写法是带验证的迁移:设置亲和性后,反复确认当前处理器编号是否已经等于目标核,不是就让出并短暂睡眠,最多重试若干次;确认落在目标核后才执行 RDMSR,读完恢复原来的掩码。
这类问题的麻烦之处在于:它既不崩溃、也不是读不到,而是读到了一个真实的、但不属于这个核的数字。八核同温的现象又太像“传感器本来就这样”,很难让人怀疑到线程调度上——这也是为什么这个点在不少工具上长期存在却没人发现。
0x19C 是每个核自己的 DTS,位置在核内的热点附近;0x1B1 是封装级的那个传感器,覆盖整个芯片但不在最热点上。所以同一次读数里,封装温度通常略低于最热的那个核,差 5 到 15 度都算正常。
这条差值有实用价值:
温度只是结果,真正决定性能的是“有没有撞墙”。芯片在同一处状态里为每类限制各留了两个标志:一个是“现在正在撞”,一个是“曾经撞过”。
| 类型 | 什么意思 | 说明 |
|---|---|---|
| 温度墙 | 核心温度已到 TjMax | 最直接的降频原因,跑分掉速多半是它 |
| PROCHOT | 降频信号被拉低 | 主板的供电与温控也会触发,不一定来自 CPU 自己 |
| 功耗墙 | 撞到 PL1 / PL2 的功率上限 | 温度不高也可能被限,笔记本尤其常见 |
| 电流墙 | 撞到电流上限 | 瞬时大负载时出现 |
| 跨域限制 | 其它域给出的限制,俗称 EDP Other | 多见于笔记本,和厂商设定的策略有关 |
关键区别在于封装级只报前三类:封装温度墙、封装 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 在起作用),要看的是持续负载下的稳态温度。
相关阅读:主板传感器芯片通道对照 · 硬盘健康度怎么看(SMART) · 怎么看内存 SPD、时序和 XMP
温度与撞墙位均为本地读取,需要管理员权限执行 RDMSR。仅支持 Intel 平台,AMD 走各自的接口。