¿Cómo se comportan los tiempos de ejecución al incrementar el número de hilos?
¿Cómo se comportan los tiempos de ejecución al incrementar el número de hilos?
Introducción
En esta entrada se analiza el rendimiento de un programa de procesamiento de imágenes BMP de 24 bits. El objetivo del programa es incrementar el brillo de una imagen utilizando una rutina SIMD en ensamblador y dividiendo el trabajo entre varios hilos.
La pregunta que se busca responder es la siguiente:
Esta pregunta es importante porque permite observar si el uso de más hilos realmente mejora el rendimiento del procesamiento de imágenes, y también permite identificar si existe un punto donde agregar más hilos deja de ser útil.
Hipótesis iniciales
Hipótesis 1:
Hipótesis 2:
Metodología y diseño de pruebas
Para comprobar las hipótesis se modificó el programa original para ejecutar automáticamente varias pruebas con diferentes números de hilos. En todas las pruebas se utilizó la misma imagen, con el fin de mantener fijo el tamaño de entrada y analizar únicamente el efecto del número de hilos.
Se realizaron 100 ejecuciones por cada configuración de hilos. En cada ejecución se midió solamente el tiempo de procesamiento del brillo, sin incluir el tiempo de carga ni el tiempo de guardado de la imagen. Esto permite que los resultados representen de forma más directa el costo del procesamiento paralelo.
1, 2, 4, 6, 8, 10, 12, 16, 20 y 32 hilos.
El programa generó un archivo llamado tiempos.csv, donde se guardaron los datos crudos de cada ejecución. Las columnas del archivo fueron:
Especificaciones de hardware
- CPU: 12th Gen Intel(R) Core(TM) i7-12650H
- Núcleos físicos: 10
- Procesadores lógicos: 16
- Frecuencia máxima reportada: 2.30 GHz
- Caché L2: 9728 KB
- Caché L3: 24576 KB
- Memoria RAM: 16 GB
- Equipo: THUNDEROBOT 911MT
- Sistema operativo: Microsoft Windows 11 Pro de 64 bits
- Entorno: Windows nativo, no virtualizado
- IDE: Microsoft Visual Studio 2022
- Configuración de compilación: Release x64
Para esta pregunta se utilizó una sola imagen, ya que el objetivo era analizar el comportamiento del tiempo al variar el número de hilos, manteniendo constante el tamaño de la imagen.
- Imagen utilizada: nature2.bmp
- Dimensiones: 3100 x 2325 pixeles
- Formato: BMP de 24 bits
- Tamaño de datos de imagen: 21622500 bytes
Cada hilo recibe una parte del arreglo de bytes de la imagen y ejecuta la rutina SIMD sobre su segmento correspondiente. El programa espera a que todos los hilos terminen antes de registrar el tiempo final.
Fragmento representativo de las configuraciones de hilos utilizadas:
Creación de hilos y procesamiento SIMD
WaitForMultipleObjects((DWORD)threadCount, threads.data(), TRUE, INFINITE);
QueryPerformanceCounter(&end);
El tiempo medido corresponde únicamente al procesamiento de la imagen, no a la lectura ni escritura del archivo BMP.
Resultados
Después de ejecutar 100 pruebas por cada configuración de hilos, se obtuvo la siguiente tabla resumen:
Hilos | Promedio ms | Mínimo ms | Máximo ms | SpeedUp
1 | 3.208688 | 2.436500 | 9.054000 | 1.0000
2 | 2.425915 | 1.845600 | 4.832300 | 1.3227
4 | 2.342777 | 1.782100 | 5.190000 | 1.3696
6 | 2.357825 | 1.853500 | 3.106200 | 1.3609
8 | 2.156250 | 1.708600 | 3.118800 | 1.4881
10 | 2.114847 | 1.718100 | 3.257100 | 1.5172
12 | 2.179509 | 1.655400 | 3.725200 | 1.4722
16 | 2.147353 | 1.716600 | 3.132200 | 1.4943
20 | 2.130497 | 1.762700 | 2.862600 | 1.5061
32 | 2.570150 | 2.020100 | 3.798300 | 1.2484
Descripción de la gráfica:
La gráfica muestra el tiempo promedio de procesamiento para cada configuración de hilos. Se observa que el tiempo disminuye al pasar de 1 hilo a configuraciones con más hilos. Sin embargo, la disminución no es lineal. A partir de cierto punto, los tiempos se mantienen muy cercanos, y con 32 hilos el tiempo promedio vuelve a aumentar.
La gráfica de SpeedUp muestra la mejora obtenida respecto a la ejecución con 1 hilo. El SpeedUp aumenta al utilizar más hilos, llegando a valores cercanos a 1.5. Sin embargo, no crece proporcionalmente al número de hilos. En la configuración de 32 hilos el SpeedUp disminuye, lo que indica una pérdida de eficiencia al utilizar demasiados hilos.
Descripción de la gráfica:
Análisis de resultados
Los resultados muestran que el uso de múltiples hilos sí mejora el tiempo de procesamiento en comparación con la ejecución de un solo hilo. Con 1 hilo, el tiempo promedio fue de 3.208688 ms. Al utilizar 10 hilos, el tiempo promedio bajó a 2.114847 ms, que fue uno de los mejores resultados obtenidos.
Esto confirma que dividir la imagen en partes y procesarlas de forma paralela permite reducir el tiempo de ejecución. Además, el uso de SIMD ayuda a que cada hilo procese varios bytes al mismo tiempo, aprovechando mejor las capacidades del procesador.
El caso más claro se observa con 32 hilos. Aunque se utilizan más hilos, el tiempo promedio aumenta a 2.570150 ms y el SpeedUp baja a 1.2484. Esto demuestra que usar más hilos no siempre significa obtener mejor rendimiento.
Confrontación de hipótesis
Hipótesis 1:
Hipótesis 2:
La segunda hipótesis se corrobora con mayor fuerza. Los resultados muestran que el tiempo baja al usar más hilos, pero llega un punto donde agregar más hilos ya no mejora de forma significativa el rendimiento. Incluso con 32 hilos el tiempo promedio empeora respecto a configuraciones menores.
Esto coincide con la idea de que, al superar cierto número de hilos, el sistema comienza a gastar más tiempo administrando, repartiendo y sincronizando el trabajo. Por lo tanto, el rendimiento puede estancarse o empeorar.
Discusión
El comportamiento observado es consistente con los principios del paralelismo. Al dividir una tarea entre varios hilos, el trabajo puede realizarse en menos tiempo siempre que existan suficientes recursos físicos para ejecutarlos de manera eficiente. No obstante, el paralelismo tiene límites.
La rutina SIMD también influye en los resultados, ya que permite procesar varios bytes de la imagen en una sola instrucción. Esto hace que el procesamiento individual de cada bloque sea muy rápido. Por esa razón, al usar demasiados hilos, el costo de administrarlos puede ser comparable o incluso mayor que el beneficio obtenido.
Conclusión
La mejora más clara ocurre al pasar de 1 hilo a configuraciones con varios hilos, pero después los tiempos se estabilizan. Cuando se utilizan demasiados hilos, como en el caso de 32 hilos, el rendimiento empeora.
El experimento demuestra que el paralelismo mejora el rendimiento, pero también que existe un límite práctico impuesto por la arquitectura del procesador y por la sobrecarga del sistema operativo.
Usar más hilos puede reducir el tiempo de ejecución, pero usar demasiados hilos no garantiza un mejor rendimiento.
Comentarios
Publicar un comentario