mac处理器的核心负载( 二 )


mac处理器的核心负载
文章图片

文章图片

为了简化核心管理 , macOS会将核心根据功能划分为2~4个相同类型的集群 , 集群可以理解成组 。然而 , 系统层面上的内核编号和powermetrics中显示的内核编号相同 , 但和活动监视器中所显示的内核编号却并不一样;因此为了行文统一 , 文中将采用活动监视器的内核编号规则 , 但根据系统集群进行编号 。在macOSMonterey12.3.1下 , M1系列的三组芯片的功能集群情况如下:
M1分别由一个E集群(包含4个E核心)和一个P集群(包含4个P核心) , 并命名为E和P0;
M1Pro/Max则由一个E集群(包含2个E核心)和两个P集群(分别包含4个P核心) , 并命名为E、P0以及P1;
M1Ultra则由一个E集群(包含4个E核心)和四个P集群(分别包含4个P核心) , 并命名为E、P0、P1、P2以及P3 。
mac处理器的核心负载
文章图片

文章图片

从理论上来讲 , 一个集群内的所有核心都会在相同的频率下运行 , 并且通常(但不总是)保持每一个集群内「核心的负载」大体相近 。极端情况下甚至会发生系统一股脑儿地把所有的任务安排到某集群中的一个核心上 。
mac处理器的核心负载
文章图片

文章图片

比如LogicPro导入素材就会出现这种极端情况
▍线程控制是如何进行的
实际应用开发中 , macOS并不提供公开的API让应用程序直接使用具体的核心、核心类型或是集群;相反 , 应用程序通常由GrandCentralDispatch使用QoS管理 , 然后macOS会使用这些设置来确定具体线程的管理策略 。
在实际情况中 , QoS最低的线程只会派发至E核集群 , 而较高的QoS的线程则可能会被派发到E或P核集群 。尽管可以通过命令工具taskpolicy或者代码中的函数setpriority()对派发进行动态修改 , 然而它却只对较高的QoS线程有效 。「最低QoS线程只在E集群上运行」的规则始终不变 。
mac处理器的核心负载
文章图片

文章图片

通过macOSAppStore安装Xcode的线程QoS就是最低的 , 完全不会使用P核
macOS自身的策略是大部分后台任务都以最低的QoS运行 。这当中包括了TimeMachine的自动备份、Spotlight索引更新以及ArchiveUtility的压缩和解压 。这当中值得一提的是 , 对于ArchiveUtility很多人可能会有一个直观的感受:下载了一个xip格式的Xcode副本 , 解压的时候需要耗时N久 , 其实这就是很多代码被限制在E核上运行所致 , 而且用户也不能主动将它调往P核上运行 。
▍后台线程(Backgroundthreads)
因为M1和M1Pro/Max芯片上的E核集群大小不同 , 前者有4个E核 , 而后者只有2个 , 所以M1和M1Pro/Max上的最低QoS线程的加载与运行方式是有不同之处的 。
在拥有4个E核的M1芯片上运行QoS为9的线程时 , 每个E核核心频率为1000M(1GHz)左右;而在只拥有2个E核的M1Pro/Max中运行同样QoS为9的线程时 , 如果只有1个线程那么E核的运行频率也同样为1000MHz , 但如果有两个或者更多 , 那么每个E核频率就会增加到2064MHz 。这样的设计确保了即使集群大小不同 , 但M1Pro/Max中E集群至少能提供和M1相同的后台任务处理性能 。
当然这里依然会有例外 , 像backupd这类拥有最低QoS的线程 , 在运行时如果同时受到来自I/O的限流 , 那么即使是在M1Pro/Max上也总会以约1000MHz的频率运行 。