C state和P state 一些体会

本文详细介绍了CPU的Cstate和Pstate特性。Cstate用于电源管理,通过关闭CPU内部组件实现节能,包括PackageCstate和CoreCstate。Pstate则是动态调整电压和频率以适应负载变化,分为多个操作点。在Linux内核中,可通过调节min_perf_pct和max_perf_pct等参数控制Pstate。理解两者区别对于优化系统性能和能耗至关重要。

C state和P state是某些cpu的一些硬件上的特性。有些朋友可能会混淆两者的关系。通过在使用过程中的调查和验证,做的笔记如下:

C stat

是电源节能的一个feature, 通过在cpu 负载不忙的时候,通过关闭cpu内部的不同器件的电源,来达到节能的目的。C state节能有两个,一个是package Cstate,一个是Core Cstate. Package对应的是一个物理cpu,Core对应的就是物理cpu内部的物理core。

对应级别如下:

C0:是一个Active状态,说明正在执行指令。就是有任务正在运行时的状态。注意,这个状态并不意味着cpu是最高频率,只要有任务在运行,cpu即使低频率也是在C0状态。从供电角度看,Cpu所有的器件都在供电。

C1:Halt状态,没有load在运行,此时core的clock关闭,此状态会很快返回C0状态。

C1E:这个也属于C1类型,但是会用最低频率和电压降低

其他见下表

 

上面的图说明不同的C state状态关闭的器件不同,频率也不同。不同C状态返回到C0状态时间也不同

 

P-state

曾经何时,人们一直认为P-state 只和cpu的频率相关。当前,P-State是cpu电压和频率的操作点的集合,电压和频率都会随着P state状态的改变而同时发生变化。P state目的根据负载是动态的增加和减少cpu电压和频率,以达到用户在节能和性能方面的需求。

 

 

上面的图,说明p state的操作点是从P0->pn, P0显示的睿频范围的频率,睿频也分等级,从HFM->Turbo

P1 是cpu的基频,就是通过lscpu看到的下面的频率。

Model name:            Intel(R) Xeon(R) CPU E5-2683 v4 @ 2.10GHz

这个表示系统在没有睿频的情况下,能达到最高的频率。

 

如何在Linux内核看P state参数

#ls /sys/devices/system/cpu/intel_pstate/

max_perf_pct min_perf_pct no_turbo num_pstates turbo_pct

P state是按照比列来调节的系统频率的。

max_perf_pct 最大的比例,这个值可以调节频率使用的最大值,一般为100%

 no_turbo  是否是睿频,0为开启睿频,1 为关闭睿频

num_pstates  处理器支持的p状态数量。这个值在0-255之前。包含了睿频和非睿频p-state。此属性是只读的。

turbo_pct 睿频的p-state占整个处理器允许的p-state的百分比,这个属性只读

min_perf_pct 最小比列,p-state能够调到最小频率的比例,这个比例最节能

如何使用

设置最大使用频率可以将min_perf_pct 设置为100%

echo 100 >  /sys/devices/system/cpu/intel_pstate/min_perf_pct

设置系统使用最高使用只能是最小频率。那就设置max_perf_pct为系统的min_perf_pct默认值,这个cpu只能在最小频率执行

P state如何计算的

 

上面的这个图是p state的动态计算的公式,是基于反馈机制计算的。有机会研究下这个公式

 

 

注意的地方:

很多人会将P state和C state混淆,即使明白的也不一定清楚P state和C state之前的联系是什么。从调查的资料看P state对应的是C0这个状态,就是有load情况的电压和频率的调节。其它的Cx都是节能状态,是没有负载的情况。换句话说,Cx(x>0)状态已经没有负载了,根本就不需要P State。

性能的误区:

只设置了高频率就好了,比如一般人都会用cpupower frequency-set -g performance这个命令这个命令使能后,某个cpu会达到睿频最大的频率。但是别忘了,当内核指令执行到类似halt和mwait指令时,cpu还是会进入C state睡眠的状态的,导致唤醒时运行效率降低,正确的是首先查看当前C state一共几个状态

从截图看一共5个状态。

如果设置高性能模式,还要加入这个命令

 cpupower -c all idle-set -D 5 

这个命令的意思是,就是关闭所有的大于5ns的C state。本例就是cpu在没有任务运行时,只能到C1-HSW这个状态,这个状态是的cpu进入运行状态只需要2ns

高性能模式并不一定是高的计算力,一般认为高性能就是cpu频率要最大在行,个人认为高性能模式分为两类,一个是高的吞吐量,一个是高的计算力

高的吞吐量:比如web服务等,这个需要频率不能波动太大,太大会抖动,就会影响服务质量;这个时候就不能设置睿频(关闭睿频)。要将频率固定到基本频率

高计算力:这个就是大家理解把cpu频率提升上去,比如可以使用睿频方式,可以使得某些cpu在繁忙的时候,cpu频率会达到最大。

高吞吐量和高计算力都是性能要求,但是设置的方式却打不同。

 

 

 

import java.util.*; public class ElevatorSimulation { // 系统配置 static final int FLOORS = 8; static final int SIMULATION_TIME = 50; // 模拟50秒 static final int PASSENGER_RATE = 5; // 每5秒生成一个乘客 static final int PASSENGER_COUNT = 10; // 共生成10名乘客 public static void main(String[] args) { // 初始化两部电梯 List<Elevator> elevators = Arrays.asList( new Elevator(1), new Elevator(2) ); // 乘客队列 List<Passenger> upWaiting = new ArrayList<>(); List<Passenger> downWaiting = new ArrayList<>(); List<Passenger> allPassengers = new ArrayList<>(); // 初始化随机数生成器 Random rand = new Random(); int passengerId = 1; System.out.println("===== 电梯模拟系统 ====="); System.out.println("模拟时长: " + SIMULATION_TIME + "秒"); System.out.println("乘客生成: 每" + PASSENGER_RATE + "秒一个,共" + PASSENGER_COUNT + "名"); System.out.println("电梯数量: " + elevators.size() + "部"); System.out.println("=".repeat(40)); // 主模拟循环 for (int time = 0; time < SIMULATION_TIME; time++) { System.out.println("\n--- 时间: " + time + "秒 ---"); // 1. 每5秒生成一个新乘客(直到生成10名) if (time % PASSENGER_RATE == 0 && passengerId <= PASSENGER_COUNT) { int start = rand.nextInt(FLOORS) + 1; int target; do { target = rand.nextInt(FLOORS) + 1; } while (target == start); Passenger p = new Passenger(passengerId++, time, start, target); allPassengers.add(p); // 按方向添加到队列 if (p.getDirection() > 0) { upWaiting.add(p); System.out.println("新乘客: " + p + " ↑ (上行)"); } else { downWaiting.add(p); System.out.println("新乘客: " + p + " ↓ (下行)"); } } // 2. 更新电梯状态 for (Elevator elevator : elevators) { elevator.updateState(time, upWaiting, downWaiting, elevators); // 处理停靠状态 if (elevator.state == Elevator.State.STOPPED) { elevator.processStop(time, upWaiting, downWaiting, elevators); } // 显示电梯状态 System.out.println(elevator.getStatus()); } // 3. 解决电梯间冲突 resolveConflicts(elevators, time); // 4. 分配空闲电梯 assignIdleElevators(elevators, upWaiting, downWaiting, time); // 5. 显示等待队列 System.out.println("等待乘客: ↑" + upWaiting.size() + " ↓" + downWaiting.size()); } // 6. 输出最终统计 printStatistics(allPassengers); } /** * 解决电梯间目标冲突 */ static void resolveConflicts(List<Elevator> elevators, int currentTime) { // 检测目标乘客冲突 Map<Integer, List<Elevator>> targetMap = new HashMap<>(); for (Elevator e : elevators) { if (e.currentTargetPassenger != null) { int passengerId = e.currentTargetPassenger.id; targetMap.computeIfAbsent(passengerId, k -> new ArrayList<>()).add(e); } } // 解决冲突:每个乘客只分配给最近的电梯 for (Map.Entry<Integer, List<Elevator>> entry : targetMap.entrySet()) { if (entry.getValue().size() > 1) { int passengerId = entry.getKey(); List<Elevator> conflicting = entry.getValue(); // 找到最近的电梯 Elevator closest = null; int minDistance = Integer.MAX_VALUE; for (Elevator e : conflicting) { int distance = Math.abs(e.currentFloor - e.currentTargetPassenger.startFloor); if (distance < minDistance) { minDistance = distance; closest = e; } } // 其他电梯取消目标 for (Elevator e : conflicting) { if (e != closest) { e.currentTargetPassenger = null; e.updateDestination(); System.out.println("冲突解决: 电梯" + e.id + " 放弃乘客" + passengerId); } } } } } /** * 为所有空闲电梯分配任务 */ static void assignIdleElevators(List<Elevator> elevators, List<Passenger> upWaiting, List<Passenger> downWaiting, int currentTime) { // 获取所有空闲电梯 List<Elevator> idleElevators = new ArrayList<>(); for (Elevator e : elevators) { if (e.state == Elevator.State.IDLE) { idleElevators.add(e); } } if (idleElevators.isEmpty()) return; // 合并等待乘客 List<Passenger> allWaiting = new ArrayList<>(); allWaiting.addAll(upWaiting); allWaiting.addAll(downWaiting); // 过滤已被接走的乘客 allWaiting.removeIf(p -> p.pickedUp); if (allWaiting.isEmpty()) return; // 为每个空闲电梯分配最近的乘客 for (Elevator e : idleElevators) { // 查找最近的未分配乘客 Passenger closest = null; int minDistance = Integer.MAX_VALUE; for (Passenger p : allWaiting) { int distance = Math.abs(p.startFloor - e.currentFloor); if (distance < minDistance) { minDistance = distance; closest = p; } } if (closest != null) { e.setTargetPassenger(closest, elevators); allWaiting.remove(closest); System.out.println("分配: 电梯" + e.id + " → 乘客" + closest.id); } } } /** * 输出统计结果 */ static void printStatistics(List<Passenger> passengers) { System.out.println("\n===== 模拟结果 ====="); System.out.println("乘客总数: " + passengers.size()); int completed = 0; int totalWaitingTime = 0; int maxWaitingTime = 0; int totalTravelTime = 0; int maxTravelTime = 0; for (Passenger p : passengers) { if (p.deliveryTime != -1) { completed++; int waitingTime = p.getWaitingTime(); totalWaitingTime += waitingTime; if (waitingTime > maxWaitingTime) maxWaitingTime = waitingTime; int travelTime = p.getTotalTime(); totalTravelTime += travelTime; if (travelTime > maxTravelTime) maxTravelTime = travelTime; } } System.out.println("完成运输: " + completed + " 人 (" + (completed * 100 / passengers.size()) + "%)"); if (completed > 0) { System.out.println("平均等待时间: " + (totalWaitingTime / completed) + "秒"); System.out.println("最长等待时间: " + maxWaitingTime + "秒"); System.out.println("平均运输时间: " + (totalTravelTime / completed) + "秒"); System.out.println("最长运输时间: " + maxTravelTime + "秒"); } // 显示未完成乘客 List<Passenger> unfinished = passengers.stream() .filter(p -> p.deliveryTime == -1) .toList(); if (!unfinished.isEmpty()) { System.out.println("\n未完成乘客:"); for (Passenger p : unfinished) { String status = p.pickedUp ? "接载中" : "等待中"; System.out.println("乘客" + p.id + ": " + status + " (等待时间: " + (50 - p.arrivalTime) + "秒)"); } } } } import java.util.*; import java.util.stream.Collectors; public class Elevator { public enum State { IDLE, MOVING, STOPPED } // 基本属性 int id; int currentFloor = 1; State state = State.IDLE; int passengers = 0; int capacity = 8; // 时间参数 int moveTime = 2; // 移动一层所需时间(秒) int stopTime = 3; // 停靠时间(秒) // 运行数据 List<Passenger> onboard = new ArrayList<>(); int timeCounter = 0; // 调度相关 int destinationFloor = -1; int direction = 0; Passenger currentTargetPassenger = null; Set<Integer> ignoredPassengerIds = new HashSet<>(); public Elevator(int id) { this.id = id; } /** * 设置目标乘客 */ public void setTargetPassenger(Passenger p, List<Elevator> allElevators) { if (p == null) return; // 清除旧目标的忽略标记 if (currentTargetPassenger != null) { allElevators.forEach(e -> e.ignoredPassengerIds.remove(currentTargetPassenger.id)); } this.currentTargetPassenger = p; destinationFloor = p.startFloor; direction = Integer.compare(destinationFloor, currentFloor); state = State.MOVING; // 通知其他电梯忽略此乘客 allElevators.stream() .filter(e -> e != this) .forEach(e -> e.ignoredPassengerIds.add(p.id)); } /** * 更新目标楼层 */ public void updateDestination() { // 优先级1: 当前目标乘客 if (currentTargetPassenger != null) { destinationFloor = currentTargetPassenger.startFloor; return; } // 优先级2: 电梯内乘客的目标楼层 if (!onboard.isEmpty()) { // 找到最近的乘客目标楼层 int closestFloor = onboard.get(0).targetFloor; int minDistance = Math.abs(closestFloor - currentFloor); for (Passenger p : onboard) { int distance = Math.abs(p.targetFloor - currentFloor); if (distance < minDistance) { minDistance = distance; closestFloor = p.targetFloor; } } destinationFloor = closestFloor; direction = Integer.compare(destinationFloor, currentFloor); return; } // 无目标 destinationFloor = -1; direction = 0; state = State.IDLE; } /** * 添加乘客到电梯 */ public void addPassenger(Passenger p, int currentTime, List<Elevator> allElevators) { if (passengers >= capacity) return; onboard.add(p); passengers++; p.pickupTime = currentTime; p.pickedUp = true; p.pickedUpBy = this.id; // 更新目的地 updateDestination(); // 从其他电梯的计划中移除该乘客 allElevators.stream() .filter(e -> e != this) .forEach(e -> { if (e.currentTargetPassenger == p) { e.currentTargetPassenger = null; e.updateDestination(); } }); } /** * 每秒更新电梯状态 */ public void updateState(int currentTime, List<Passenger> upWaiting, List<Passenger> downWaiting, List<Elevator> allElevators) { timeCounter++; switch (state) { case IDLE: // 空闲状态不执行操作 break; case MOVING: if (timeCounter >= moveTime) { currentFloor += direction; timeCounter = 0; // 检查是否到达目标楼层 if (currentFloor == destinationFloor) { state = State.STOPPED; } // 检查是否有顺路乘客 else if (checkForPickups(currentFloor, upWaiting, downWaiting)) { state = State.STOPPED; } } break; case STOPPED: if (timeCounter >= stopTime) { state = State.MOVING; timeCounter = 0; updateDestination(); } break; } } /** * 处理停靠点上下客 */ public void processStop(int currentTime, List<Passenger> upWaiting, List<Passenger> downWaiting, List<Elevator> allElevators) { // 1. 下客 List<Passenger> toUnload = new ArrayList<>(); for (Passenger p : onboard) { if (p.targetFloor == currentFloor) { toUnload.add(p); p.deliveryTime = currentTime; } } onboard.removeAll(toUnload); passengers -= toUnload.size(); // 2. 上客 - 目标乘客优先 if (currentTargetPassenger != null && currentTargetPassenger.startFloor == currentFloor && !currentTargetPassenger.pickedUp) { addPassenger(currentTargetPassenger, currentTime, allElevators); currentTargetPassenger = null; } // 3. 上客 - 顺路乘客 List<Passenger> directionPassengers = direction > 0 ? upWaiting : downWaiting; Iterator<Passenger> it = directionPassengers.iterator(); while (it.hasNext() && passengers < capacity) { Passenger p = it.next(); if (p.startFloor == currentFloor && !ignoredPassengerIds.contains(p.id) && !p.pickedUp) { addPassenger(p, currentTime, allElevators); it.remove(); } } // 更新目的地 updateDestination(); } // 检查当前楼层是否有可接载的乘客 private boolean checkForPickups(int floor, List<Passenger> upWaiting, List<Passenger> downWaiting) { List<Passenger> directionPassengers = direction > 0 ? upWaiting : downWaiting; for (Passenger p : directionPassengers) { if (p.startFloor == floor && !ignoredPassengerIds.contains(p.id) && !p.pickedUp) { return true; } } return false; } // 获取状态摘要 public String getStatus() { String stateStr = state == State.IDLE ? "空闲" : state == State.MOVING ? "移动中" : "停靠中"; String dirStr = direction > 0 ? "↑" : direction < 0 ? "↓" : ""; String targetStr = destinationFloor > 0 ? destinationFloor + "楼" : "无"; return String.format("电梯%d [%d楼] %s %s 乘客:%d 目标:%s", id, currentFloor, stateStr, dirStr, passengers, targetStr); } } import java.util.*; public class ElevatorSimulation { // 系统配置 static final int FLOORS = 8; static final int SIMULATION_TIME = 50; // 模拟50秒 static final int PASSENGER_RATE = 5; // 每5秒生成一个乘客 static final int PASSENGER_COUNT = 10; // 共生成10名乘客 public static void main(String[] args) { // 初始化两部电梯 List<Elevator> elevators = Arrays.asList( new Elevator(1), new Elevator(2) ); // 乘客队列 List<Passenger> upWaiting = new ArrayList<>(); List<Passenger> downWaiting = new ArrayList<>(); List<Passenger> allPassengers = new ArrayList<>(); // 初始化随机数生成器 Random rand = new Random(); int passengerId = 1; System.out.println("===== 电梯模拟系统 ====="); System.out.println("模拟时长: " + SIMULATION_TIME + "秒"); System.out.println("乘客生成: 每" + PASSENGER_RATE + "秒一个,共" + PASSENGER_COUNT + "名"); System.out.println("电梯数量: " + elevators.size() + "部"); System.out.println("=".repeat(40)); // 主模拟循环 for (int time = 0; time < SIMULATION_TIME; time++) { System.out.println("\n--- 时间: " + time + "秒 ---"); // 1. 每5秒生成一个新乘客(直到生成10名) if (time % PASSENGER_RATE == 0 && passengerId <= PASSENGER_COUNT) { int start = rand.nextInt(FLOORS) + 1; int target; do { target = rand.nextInt(FLOORS) + 1; } while (target == start); Passenger p = new Passenger(passengerId++, time, start, target); allPassengers.add(p); // 按方向添加到队列 if (p.getDirection() > 0) { upWaiting.add(p); System.out.println("新乘客: " + p + " ↑ (上行)"); } else { downWaiting.add(p); System.out.println("新乘客: " + p + " ↓ (下行)"); } } // 2. 更新电梯状态 for (Elevator elevator : elevators) { elevator.updateState(time, upWaiting, downWaiting, elevators); // 处理停靠状态 if (elevator.state == Elevator.State.STOPPED) { elevator.processStop(time, upWaiting, downWaiting, elevators); } // 显示电梯状态 System.out.println(elevator.getStatus()); } // 3. 解决电梯间冲突 resolveConflicts(elevators, time); // 4. 分配空闲电梯 assignIdleElevators(elevators, upWaiting, downWaiting, time); // 5. 显示等待队列 System.out.println("等待乘客: ↑" + upWaiting.size() + " ↓" + downWaiting.size()); } // 6. 输出最终统计 printStatistics(allPassengers); } /** * 解决电梯间目标冲突 */ static void resolveConflicts(List<Elevator> elevators, int currentTime) { // 检测目标乘客冲突 Map<Integer, List<Elevator>> targetMap = new HashMap<>(); for (Elevator e : elevators) { if (e.currentTargetPassenger != null) { int passengerId = e.currentTargetPassenger.id; targetMap.computeIfAbsent(passengerId, k -> new ArrayList<>()).add(e); } } // 解决冲突:每个乘客只分配给最近的电梯 for (Map.Entry<Integer, List<Elevator>> entry : targetMap.entrySet()) { if (entry.getValue().size() > 1) { int passengerId = entry.getKey(); List<Elevator> conflicting = entry.getValue(); // 找到最近的电梯 Elevator closest = null; int minDistance = Integer.MAX_VALUE; for (Elevator e : conflicting) { int distance = Math.abs(e.currentFloor - e.currentTargetPassenger.startFloor); if (distance < minDistance) { minDistance = distance; closest = e; } } // 其他电梯取消目标 for (Elevator e : conflicting) { if (e != closest) { e.currentTargetPassenger = null; e.updateDestination(); System.out.println("冲突解决: 电梯" + e.id + " 放弃乘客" + passengerId); } } } } } /** * 为所有空闲电梯分配任务 */ static void assignIdleElevators(List<Elevator> elevators, List<Passenger> upWaiting, List<Passenger> downWaiting, int currentTime) { // 获取所有空闲电梯 List<Elevator> idleElevators = new ArrayList<>(); for (Elevator e : elevators) { if (e.state == Elevator.State.IDLE) { idleElevators.add(e); } } if (idleElevators.isEmpty()) return; // 合并等待乘客 List<Passenger> allWaiting = new ArrayList<>(); allWaiting.addAll(upWaiting); allWaiting.addAll(downWaiting); // 过滤已被接走的乘客 allWaiting.removeIf(p -> p.pickedUp); if (allWaiting.isEmpty()) return; // 为每个空闲电梯分配最近的乘客 for (Elevator e : idleElevators) { // 查找最近的未分配乘客 Passenger closest = null; int minDistance = Integer.MAX_VALUE; for (Passenger p : allWaiting) { int distance = Math.abs(p.startFloor - e.currentFloor); if (distance < minDistance) { minDistance = distance; closest = p; } } if (closest != null) { e.setTargetPassenger(closest, elevators); allWaiting.remove(closest); System.out.println("分配: 电梯" + e.id + " → 乘客" + closest.id); } } } /** * 输出统计结果 */ static void printStatistics(List<Passenger> passengers) { System.out.println("\n===== 模拟结果 ====="); System.out.println("乘客总数: " + passengers.size()); int completed = 0; int totalWaitingTime = 0; int maxWaitingTime = 0; int totalTravelTime = 0; int maxTravelTime = 0; for (Passenger p : passengers) { if (p.deliveryTime != -1) { completed++; int waitingTime = p.getWaitingTime(); totalWaitingTime += waitingTime; if (waitingTime > maxWaitingTime) maxWaitingTime = waitingTime; int travelTime = p.getTotalTime(); totalTravelTime += travelTime; if (travelTime > maxTravelTime) maxTravelTime = travelTime; } } System.out.println("完成运输: " + completed + " 人 (" + (completed * 100 / passengers.size()) + "%)"); if (completed > 0) { System.out.println("平均等待时间: " + (totalWaitingTime / completed) + "秒"); System.out.println("最长等待时间: " + maxWaitingTime + "秒"); System.out.println("平均运输时间: " + (totalTravelTime / completed) + "秒"); System.out.println("最长运输时间: " + maxTravelTime + "秒"); } // 显示未完成乘客 List<Passenger> unfinished = passengers.stream() .filter(p -> p.deliveryTime == -1) .toList(); if (!unfinished.isEmpty()) { System.out.println("\n未完成乘客:"); for (Passenger p : unfinished) { String status = p.pickedUp ? "接载中" : "等待中"; System.out.println("乘客" + p.id + ": " + status + " (等待时间: " + (50 - p.arrivalTime) + "秒)"); } } } } 根据这个模板生成一份实验报告,要在各个地方加上相应的代码
06-23
评论 5
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值