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:
commit
65f16ce99b
|
|
@ -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
|
||||||
|
|
@ -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
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue