Benchmarking¶
Para evaluar lo que esperamos de la paralelización, que es el tiempo de ejecución, debemos realizar mediciones del tiempo que tarda un algoritmo en resolver un problema enfrentando su versión secuencial con su versión paralela.
A esto se le conoce como evaluación comparativa. Se toma una ejecución secuencial y se compara con sus versiones paralelas.
El tiempo de ejecución depende de varios factores:
- Características de la CPU (velocidad, arquitectura, memoria caché)
- Latencia de acceso a la RAM
- Procesos del lenguaje, como el recolector de basura, planificación de hilos, etc.
Para evaluar correctamente la ejecución de un programa debemos considerar los múltiples factores, entonces se debe realizar:
- Múltiples repeticiones y tomar los promedios
- Tratamiento estadístico para descartar casos atípicos
- Medir en estado estable (después del calentamiento de la máquina virtual)
- Prevenir anomalías (comportamientos poco frecuentes)
Scalameter¶
Esta es una librería externa, es necesario agregarla en Gradle por ejemplo:
dependencies {
// Otras dependencias
implementation 'com.storm-enroute:scalameter-core_2.13:0.21'
}
Para usar Scalameter:
import org.scalameter._
Para usarlo utilizamos measure:
/*
* This Scala source file was generated by the Gradle 'init' task.
*/
package taller
import org.scalameter._
object App {
def main(args: Array[String]): Unit = {
val n = 1000000
val t1 = measure {
(1 to n).sum
}
val t2 = measure {
(1 to n).sum
}
val t3 = measure {
(1 to n).sum
}
val t4 = measure {
(1 to n).sum
}
println(t1)
println(t2)
println(t3)
println(t4)
}
def greeting(): String = "Hello, world!"
}
Da como resultado:
1.968934 ms
0.010961 ms
0.007434 ms
0.009497 ms
Observar que el primero está tardando alrededor de 100 veces los otros, esto es porque la máquina virtual (JVM) no está en estado estable, es decir está cargando componentes.
Para resolverlo vamos a utilizar withWarmer. Este va a hacer que la medición espere hasta que la JVM esté en estado estable:
/*
* This Scala source file was generated by the Gradle 'init' task.
*/
package taller
import org.scalameter._
object App {
def main(args: Array[String]): Unit = {
val n = 1000000
val t1 = withWarmer(new Warmer.Default) measure {
(1 to n).sum
}
val t2 = withWarmer(new Warmer.Default) measure {
(1 to n).sum
}
val t3 = withWarmer(new Warmer.Default) measure {
(1 to n).sum
}
val t4 = withWarmer(new Warmer.Default) measure {
(1 to n).sum
}
println(t1)
println(t2)
println(t3)
println(t4)
}
def greeting(): String = "Hello, world!"
}
Observese:
0.01065 ms
0.004859 ms
0.004288 ms
0.004158 ms
Observar que el primero tarda mucho menos, aunque sigue habiendo cierta latencia.
Tabla de Resumen de Conceptos¶
| Concepto | Definición | Propósito/Importancia | Herramienta/Implementación |
|---|---|---|---|
| Benchmarking | Proceso de medición del rendimiento de algoritmos | Comparar versiones secuenciales vs paralelas | Evaluación comparativa |
| Tiempo de ejecución | Duración que tarda un algoritmo en completarse | Métrica principal de rendimiento | Medido en milisegundos/segundos |
| Factores que afectan el tiempo | Elementos que influyen en las mediciones | CPU, RAM, procesos del lenguaje | Considerar en análisis |
| Estado estable de JVM | Condición óptima después del calentamiento | Mediciones consistentes y confiables | withWarmer en Scalameter |
| Scalameter | Librería para benchmarking en Scala | Mediciones precisas y controladas | Dependencia de Gradle |
| Múltiples repeticiones | Ejecutar varias veces el mismo código | Reducir variabilidad y obtener promedios | Práctica esencial |
| Tratamiento estadístico | Análisis de datos para eliminar outliers | Resultados más confiables | Parte del proceso de benchmarking |
| Calentamiento de JVM | Período inicial de optimización | Evitar mediciones infladas | Resuelto con Warmer.Default |
Conceptos importantes destacados: - Benchmarking - Tiempo de ejecución - Estado estable de JVM - Scalameter - Evaluación comparativa - Múltiples repeticiones - Calentamiento de la máquina virtual - Mediciones confiables
Observación clave: Las mediciones iniciales sin calentamiento pueden ser hasta 100 veces más lentas debido a la carga inicial de componentes de la JVM. El uso de withWarmer es esencial para obtener mediciones precisas y representativas del rendimiento real del algoritmo.