implemented multiple fans
This commit is contained in:
@@ -69,8 +69,8 @@ impl OptimizerEngine {
|
||||
.unwrap_or(0.0)
|
||||
}
|
||||
|
||||
/// Finds the "Silicon Knee" - the point where performance per watt plateaus
|
||||
/// and thermal density spikes.
|
||||
/// Finds the "Silicon Knee" - the point where performance per watt (efficiency)
|
||||
/// starts to diminish significantly and thermal density spikes.
|
||||
pub fn find_silicon_knee(&self, profile: &ThermalProfile) -> f32 {
|
||||
if profile.points.len() < 3 {
|
||||
return profile.points.last().map(|p| p.power_w).unwrap_or(15.0);
|
||||
@@ -82,27 +82,42 @@ impl OptimizerEngine {
|
||||
let mut best_pl = points[0].power_w;
|
||||
let mut max_score = f32::MIN;
|
||||
|
||||
// Use a sliding window (3 points) to calculate gradients more robustly
|
||||
for i in 1..points.len() - 1 {
|
||||
let prev = &points[i - 1];
|
||||
let curr = &points[i];
|
||||
let next = &points[i + 1];
|
||||
|
||||
// 1. Performance Gradient (dMHz/dW)
|
||||
let dmhz_dw_prev = (curr.freq_mhz - prev.freq_mhz) / (curr.power_w - prev.power_w).max(0.1);
|
||||
let dmhz_dw_next = (next.freq_mhz - curr.freq_mhz) / (next.power_w - curr.power_w).max(0.1);
|
||||
let freq_diminish = dmhz_dw_prev - dmhz_dw_next;
|
||||
// 1. Efficiency Metric (Throughput per Watt)
|
||||
// If throughput is 0 (unsupported), fallback to Frequency per Watt
|
||||
let efficiency_curr = if curr.throughput > 0.0 {
|
||||
curr.throughput as f32 / curr.power_w.max(0.1)
|
||||
} else {
|
||||
curr.freq_mhz / curr.power_w.max(0.1)
|
||||
};
|
||||
|
||||
let efficiency_next = if next.throughput > 0.0 {
|
||||
next.throughput as f32 / next.power_w.max(0.1)
|
||||
} else {
|
||||
next.freq_mhz / next.power_w.max(0.1)
|
||||
};
|
||||
|
||||
// 2. Thermal Gradient (d2T/dW2)
|
||||
// Diminishing returns: how much efficiency drops per additional watt
|
||||
let efficiency_drop = (efficiency_curr - efficiency_next) / (next.power_w - curr.power_w).max(0.1);
|
||||
|
||||
// 2. Thermal Acceleration (d2T/dW2)
|
||||
let dt_dw_prev = (curr.temp_c - prev.temp_c) / (curr.power_w - prev.power_w).max(0.1);
|
||||
let dt_dw_next = (next.temp_c - curr.temp_c) / (next.power_w - curr.power_w).max(0.1);
|
||||
let temp_accel = (dt_dw_next - dt_dw_prev) / (next.power_w - prev.power_w).max(0.1);
|
||||
|
||||
// 3. Wall Detection
|
||||
let is_throttling = next.freq_mhz < curr.freq_mhz;
|
||||
let penalty = if is_throttling { 2000.0 } else { 0.0 };
|
||||
// 3. Wall Detection (Any drop in absolute frequency/throughput is a hard wall)
|
||||
let is_throttling = next.freq_mhz < curr.freq_mhz || (next.throughput > 0.0 && next.throughput < curr.throughput);
|
||||
let penalty = if is_throttling { 5000.0 } else { 0.0 };
|
||||
|
||||
// Heuristic scoring: Weight thermal acceleration and diminishing frequency gains
|
||||
let score = (freq_diminish * 2.0) + (temp_accel * 10.0) - penalty;
|
||||
// Heuristic scoring:
|
||||
// - Higher score is "Better" (The Knee is the peak of this curve)
|
||||
// - We want high efficiency (low drop) and low thermal acceleration.
|
||||
let score = (efficiency_curr * 10.0) - (efficiency_drop * 50.0) - (temp_accel * 20.0) - penalty;
|
||||
|
||||
if score > max_score {
|
||||
max_score = score;
|
||||
|
||||
Reference in New Issue
Block a user