feat: benchmark de CPU - velocidad teórica vs real

Benchmark en Rust que mide la velocidad real del procesador comparada
con la velocidad teórica del fabricante. Incluye:
- Test de un solo núcleo
- Test de todos los núcleos
- Test de ráfaga (burst)
- Explicaciones para usuarios no técnicos

🤖 Generated with Claude Code

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Andrés Eduardo García Márquez 2026-01-28 12:55:27 -05:00
commit 65f16ce99b
2 changed files with 276 additions and 0 deletions

11
Cargo.toml Normal file
View File

@ -0,0 +1,11 @@
[package]
name = "cpu_bench"
version = "0.1.0"
edition = "2021"
[dependencies]
num_cpus = "1.16"
[profile.release]
opt-level = 3
lto = true

265
src/main.rs Normal file
View File

@ -0,0 +1,265 @@
use std::sync::atomic::{AtomicBool, AtomicU64, Ordering};
use std::sync::Arc;
use std::thread;
use std::time::{Duration, Instant};
const NUM_CORES: usize = 8;
const TEST_DURATION: u64 = 10;
// Especificaciones del Snapdragon 6s Gen 3
const PERF_CORES: usize = 4;
const PERF_FREQ_GHZ: f64 = 2.3;
const EFF_CORES: usize = 4;
const EFF_FREQ_GHZ: f64 = 2.0;
fn main() {
println!("╔════════════════════════════════════════════════════════════════╗");
println!("║ VELOCIDAD DE CPU: TEORICA vs REAL ║");
println!("║ Honor LGN-NX3 - Snapdragon 6s Gen 3 ║");
println!("╚════════════════════════════════════════════════════════════════╝\n");
// Velocidad teórica
let theoretical_total = (PERF_CORES as f64 * PERF_FREQ_GHZ) +
(EFF_CORES as f64 * EFF_FREQ_GHZ);
let theoretical_avg = theoretical_total / NUM_CORES as f64;
println!("┌────────────────────────────────────────────────────────────────┐");
println!("│ ESPECIFICACIONES DEL FABRICANTE (Velocidad Teorica) │");
println!("├────────────────────────────────────────────────────────────────┤");
println!("│ │");
println!("│ Nucleos de RENDIMIENTO (rapidos): │");
println!("{} nucleos x {:.1} GHz = {:.1} GHz │",
PERF_CORES, PERF_FREQ_GHZ, PERF_CORES as f64 * PERF_FREQ_GHZ);
println!("│ │");
println!("│ Nucleos de EFICIENCIA (ahorro bateria): │");
println!("{} nucleos x {:.1} GHz = {:.1} GHz │",
EFF_CORES, EFF_FREQ_GHZ, EFF_CORES as f64 * EFF_FREQ_GHZ);
println!("│ │");
println!("│ TOTAL TEORICO: {:.1} GHz ({} nucleos) │",
theoretical_total, NUM_CORES);
println!("│ PROMEDIO: {:.2} GHz por nucleo │", theoretical_avg);
println!("│ │");
println!("└────────────────────────────────────────────────────────────────┘\n");
println!("Midiendo velocidad REAL durante {} segundos...\n", TEST_DURATION);
// Test 1: Velocidad máxima (single-thread)
print!(" [1/3] Un solo nucleo a maxima potencia... ");
let single_ghz = measure_single_core();
println!("{:.2} GHz", single_ghz);
// Test 2: Todos los núcleos
print!(" [2/3] Todos los nucleos trabajando... ");
let (multi_total, multi_per_core) = measure_all_cores();
println!("{:.2} GHz total", multi_total);
// Test 3: Ráfaga corta (burst)
print!(" [3/3] Velocidad pico (rafaga corta)... ");
let burst_ghz = measure_burst();
println!("{:.2} GHz", burst_ghz);
// Calcular eficiencias
let single_eff = (single_ghz / PERF_FREQ_GHZ) * 100.0;
let multi_eff = (multi_total / theoretical_total) * 100.0;
let burst_eff = (burst_ghz / PERF_FREQ_GHZ) * 100.0;
println!("\n");
println!("╔════════════════════════════════════════════════════════════════╗");
println!("║ RESULTADOS COMPARATIVOS ║");
println!("╠════════════════════════════════════════════════════════════════╣");
println!("║ ║");
println!("║ TEORICO REAL EFICIENCIA ║");
println!("║ ──────────────────────────────────────────────────────────── ║");
println!("║ ║");
println!("║ Un nucleo (max): {:.1} GHz {:.2} GHz {:>5.1}% ║",
PERF_FREQ_GHZ, single_ghz, single_eff);
println!("║ Todos ({} nucleos): {:.1} GHz {:.2} GHz {:>5.1}% ║",
NUM_CORES, theoretical_total, multi_total, multi_eff);
println!("║ Pico (rafaga): {:.1} GHz {:.2} GHz {:>5.1}% ║",
PERF_FREQ_GHZ, burst_ghz, burst_eff);
println!("║ ║");
println!("╠════════════════════════════════════════════════════════════════╣");
println!("║ ║");
println!("║ VELOCIDAD REAL DE TU PROCESADOR ║");
println!("║ ══════════════════════════════ ║");
println!("║ ║");
println!("║ Sostenida (uso continuo): {:.2} GHz ║", multi_total);
println!("║ Por nucleo (promedio): {:.2} GHz ║", multi_per_core);
println!("║ Pico maximo alcanzado: {:.2} GHz ║", burst_ghz);
println!("║ ║");
println!("╚════════════════════════════════════════════════════════════════╝");
// Explicación visual
println!("\n");
println!("┌────────────────────────────────────────────────────────────────┐");
println!("│ COMPARACION VISUAL │");
println!("├────────────────────────────────────────────────────────────────┤");
println!("│ │");
let bar_theoretical = "".repeat(20);
let bar_len = ((multi_eff / 100.0) * 20.0).min(20.0) as usize;
let bar_real = "".repeat(bar_len);
let bar_empty = "".repeat(20 - bar_len);
println!("│ Velocidad TEORICA (lo que dice el fabricante): │");
println!("│ [{}] {:.1} GHz │", bar_theoretical, theoretical_total);
println!("│ │");
println!("│ Velocidad REAL (lo que realmente tienes): │");
println!("│ [{}{}] {:.1} GHz │", bar_real, bar_empty, multi_total);
println!("│ │");
println!("│ Diferencia: {:.1} GHz ({:.0}% del teorico) │",
theoretical_total - multi_total, multi_eff);
println!("│ │");
println!("└────────────────────────────────────────────────────────────────┘");
// Explicación para no técnicos
println!("\n");
println!("┌────────────────────────────────────────────────────────────────┐");
println!("│ ¿POR QUE LA VELOCIDAD REAL ES MENOR? │");
println!("│ (Explicacion sencilla) │");
println!("├────────────────────────────────────────────────────────────────┤");
println!("│ │");
println!("│ 1. AHORRO DE BATERIA │");
println!("│ Android reduce la velocidad para que la bateria dure mas. │");
println!("│ Si siempre fuera al maximo, se acabaria en 2-3 horas. │");
println!("│ │");
println!("│ 2. TEMPERATURA │");
println!("│ Si el procesador se calienta mucho, baja la velocidad │");
println!("│ automaticamente para no danarse (thermal throttling). │");
println!("│ │");
println!("│ 3. LIMITACIONES DEL SISTEMA │");
println!("│ Android y Termux no pueden usar el 100% del hardware │");
println!("│ por razones de seguridad y estabilidad. │");
println!("│ │");
println!("├────────────────────────────────────────────────────────────────┤");
println!("│ │");
println!("│ ¿ES MALO? │");
println!("│ ──────── │");
if multi_eff >= 70.0 {
println!("│ NO. Tu telefono alcanza {:.0}% de su velocidad teorica. │", multi_eff);
println!("│ Eso es MUY BUENO. La mayoria de telefonos logran 40-60%. │");
} else if multi_eff >= 50.0 {
println!("│ NO. Tu telefono alcanza {:.0}% de su velocidad teorica. │", multi_eff);
println!("│ Eso es NORMAL. El sistema prioriza bateria sobre velocidad. │");
} else {
println!("│ Tu telefono alcanza {:.0}% de su velocidad teorica. │", multi_eff);
println!("│ Es bajo, pero normal en Android. Prioriza bateria. │");
}
println!("│ │");
println!("├────────────────────────────────────────────────────────────────┤");
println!("│ │");
println!("│ ANALOGIA DEL CARRO │");
println!("│ ─────────────────── │");
println!("│ │");
println!("│ Es como un carro que dice \"velocidad maxima: 200 km/h\"");
println!("│ pero en la ciudad solo andas a 60 km/h por los semaforos. │");
println!("│ │");
println!("│ • Velocidad maxima del carro (teorica): {:.0} km/h │", theoretical_total * 10.0);
println!("│ • Velocidad real en ciudad (practica): {:.0} km/h │", multi_total * 10.0);
println!("│ │");
println!("│ El carro PUEDE ir mas rapido, pero las condiciones │");
println!("│ (semaforos = bateria, trafico = otras apps) lo limitan. │");
println!("│ │");
println!("└────────────────────────────────────────────────────────────────┘");
// Resumen final
println!("\n");
println!("╔════════════════════════════════════════════════════════════════╗");
println!("║ RESUMEN FINAL ║");
println!("╠════════════════════════════════════════════════════════════════╣");
println!("║ ║");
println!("║ Tu procesador Snapdragon 6s Gen 3: ║");
println!("║ ║");
println!("║ • Velocidad TEORICA: {:.1} GHz (8 nucleos combinados) ║", theoretical_total);
println!("║ • Velocidad REAL: {:.1} GHz (lo que usas en la practica) ║", multi_total);
println!("║ • Eficiencia: {:.0}% ║", multi_eff);
println!("║ ║");
println!("║ En palabras simples: Tu telefono usa {:.1} de cada {:.1} GHz ║",
multi_total, theoretical_total);
println!("║ disponibles. El resto se guarda para cuidar la bateria. ║");
println!("║ ║");
println!("╚════════════════════════════════════════════════════════════════╝");
}
fn measure_single_core() -> f64 {
let iterations = 50_000_000u64;
let start = Instant::now();
let mut x: u64 = 1;
for _ in 0..iterations {
x = x.wrapping_mul(6364136223846793005).wrapping_add(1);
x ^= x >> 33;
}
std::hint::black_box(x);
let elapsed = start.elapsed().as_secs_f64();
// ~3 operaciones por iteración, normalizado a GHz equivalente
(iterations as f64 * 3.0) / elapsed / 1e9
}
fn measure_all_cores() -> (f64, f64) {
let running = Arc::new(AtomicBool::new(true));
let total_ops = Arc::new(AtomicU64::new(0));
let mut handles = Vec::with_capacity(NUM_CORES);
for _ in 0..NUM_CORES {
let r = Arc::clone(&running);
let ops = Arc::clone(&total_ops);
handles.push(thread::spawn(move || {
let mut x: u64 = 1;
let mut local_ops = 0u64;
while r.load(Ordering::Relaxed) {
for _ in 0..10000 {
x = x.wrapping_mul(6364136223846793005).wrapping_add(1);
x ^= x >> 33;
}
local_ops += 10000;
}
ops.fetch_add(local_ops, Ordering::Relaxed);
std::hint::black_box(x);
}));
}
thread::sleep(Duration::from_secs(TEST_DURATION));
running.store(false, Ordering::Relaxed);
for h in handles {
h.join().unwrap();
}
let total = total_ops.load(Ordering::Relaxed);
let ops_per_sec = total as f64 / TEST_DURATION as f64;
let total_ghz = (ops_per_sec * 3.0) / 1e9;
let per_core = total_ghz / NUM_CORES as f64;
(total_ghz, per_core)
}
fn measure_burst() -> f64 {
// Medir velocidad pico con ráfagas cortas
let mut max_ghz = 0.0f64;
for _ in 0..5 {
let iterations = 10_000_000u64;
let start = Instant::now();
let mut x: u64 = 1;
for _ in 0..iterations {
x = x.wrapping_mul(6364136223846793005).wrapping_add(1);
x ^= x >> 33;
}
std::hint::black_box(x);
let elapsed = start.elapsed().as_secs_f64();
let ghz = (iterations as f64 * 3.0) / elapsed / 1e9;
if ghz > max_ghz {
max_ghz = ghz;
}
thread::sleep(Duration::from_millis(100));
}
max_ghz
}