Algoritmos, Eficiencia
Optimización de algoritmos para mejorar la eficiencia y el coste energético
¿Sabías que los datacenters consumen más energía que algunos países pequeños? Según la Agencia Internacional de Energía, más del 1% de la energía mundial es utilizada por ellos.
En el mundo empresarial, la optimización de algoritmos no es solo una cuestión de reducir tiempos de ejecución para mejorar el rendimiento. La eficiencia también se puede traducir en un menor consumo eléctrico, así como en un menor impacto medio ambiental.
Vamos a ver cómo podemos marcar la diferencia, adaptando nuestros algoritmos y aprovechando las últimas tecnologías, como las proporcionadas por AWS.
¿Cómo podemos entender la eficiencia?
Cuando hablamos de eficiencia en algoritmos, hay que tener en cuenta dos factores principales: eficiencia en tiempo (velocidad a la que se procesa un algoritmo) y eficiencia en espacio (memoria utilizada para ello).
Diseño algorítmico respecto al software
Consiste en reducir el número de operaciones utilizadas para resolver un problema (complejidad). Para representarla, usamos la notación Big-O , que describe cómo escala el coste de un algoritmo ignorando los detalles pequeños y centrándose en el comportamiento a gran escala.
Veamos algunos ejemplos:
O(1) – Constante: Siempre tarda lo mismo, sin importar el tamaño de la entrada. Ejemplo: Acceder al elemento i de un array.
O(log n) – Logarítmica: Cada vez que el tamaño de la entrada se duplica, solo necesitas una operación extra. Ejemplo: Búsqueda en un árbol binario equilibrado.
O(n) – Lineal: El tiempo de ejecución crece proporcionalmente al tamaño de la entrada. Ejemplo: Buscar un elemento en una lista no ordenada.
O(n log n) – Quasilineal: Más lento que lineal, pero común en algoritmos eficientes de ordenación, al ser más eficiente que el coste cuadrático. Ejemplo: Los conocidos algoritmos Merge Sort o Quick Sort.
O(n^2) – Cuadrática: Cada elemento de la entrada interactúa con todos los demás. Ejemplo: Comparar cada par de elementos en una lista.
Es de gran importancia buscar la manera de usar la complejidad más baja posible en nuestro código, ya que no solo nos servirá para reducir el tiempo de ejecución, sino también para optimizar la cantidad de memoria y energía utilizada.
Por ejemplo:
En un sistema de búsqueda de datos, si tenemos un algoritmo de búsqueda lineal (O(n)), conviene invertir tiempo en ordenar primero la lista, para poder luego utilizar, por ejemplo, una búsqueda binaria, haciendo que nuestras búsquedas sean ahora todas O(log(n)).
Otro ejemplo práctico es a la hora de ordenar grandes datasets, buscar siempre el mejor método posible, reemplazando algoritmos como Bubble Sort (O(n^2)) por otros más eficientes como Merge Sort (O(n log n)).
Cuando sea posible, nos podemos valer también de estructuras de datos como HashMap, aprovechando que en promedio, su acceso a datos es constante (O(1)), permitiendo transformar por ejemplo, un proceso que cuenta las apariciones de cada elemento en una lista, de O(n^2) a O(n) (al ser necesario recorrerla solo una vez).
Diseño algorítmico adaptado al hardware
No todos los procesadores son iguales. Con el auge de arquitecturas como ARM-Graviton de Amazon, diseñadas para eficiencia energética, es vital optimizar los algoritmos considerando el hardware en el que serán ejecutados.
Procesadores ARM: Estos chips predominan en la computación en la nube gracias a su bajo consumo energético. Los algoritmos que aprovechan cálculos vectoriales y paralelismo suelen rendir mejor en estos procesadores.
Procesadores tradicionales x86: Aunque son más potentes en tareas de alto rendimiento, su consumo energético es mayor. Por ello, para tareas simples y repetitivas, los ARM resultan una elección más sostenible.
Veamos un ejemplo:
Supongamos que estamos entrenando un modelo de machine learning en la nube. Los procesadores ARM-Graviton (Como EC2-Graviton de AWS), nos darán un rendimiento similar a un procesador x86, pero consumiendo una menor energía (alrededor del 40% para ciertas cargas).
Si podemos adaptar nuestro código para usar SIMD (Instrucciones únicas sobre múltiples datos) para poder aprovechar la capacidad de estos procesadores de dividir la carga de trabajo en operaciones simultáneas (paralelismo), podremos marcar la diferencia en coste y sostenibilidad.
Impulsando la Eficiencia y la Sostenibilidad en la Tecnología
Optimización algorítmica: Podemos disminuir la complejidad computacional de nuestros algoritmos y utilizar estructuras de datos adecuadas para mejorar nuestro rendimiento en tiempo y espacio, reduciendo también el consumo energético.
Adaptación al hardware: Usando hardware optimizado (como ARM-Graviton) para ciertas operaciones, podemos maximizar el rendimiento con un menor consumo. Ajustar nuestros algoritmos para beneficiarse de las capacidades del hardware (por ejemplo, el paralelismo) puede significar una gran diferencia.
Sostenibilidad: La mejora de eficiencia, no solo supone una mejora de la calidad de nuestras soluciones, sino que, al requerir menos energía y potencia de computación para las mismas operaciones, se reducen los costes y se minimiza la huella de carbono.
En ARENA conocemos la importancia de emplear tiempo en mejorar la eficiencia de nuestras aplicaciones, lo que representa una inversión en calidad, ahorro y responsabilidad ambiental.