Paralelo vs Secuencial.
Muchas de las aplicaciones en la vida real se ejecutan simultáneamente, como es el caso de una simple ventana de Internet hasta algo tan complejo como un sistema operativo. Mientras usted lee tranquilamente este blog, puede escuchar música o revisar su correo electrónico. En muchas aplicaciones, es necesario ejecutar tareas de forma simultánea para ahorrar tiempo y mejorar la eficiencia, lo que en el día de hoy es sinónimo de ahorro de dinero y esfuerzo.
Originalmente, en el ámbito de la programación en paralelo, una sola computadora ejecutaba una tarea a la vez y se conectaba con otras para finalmente combinar los resultados de cada una. Hoy en día, ya no se utilizan esos métodos, dado que los procesadores cuentan con múltiples hilos.
Comparación de eficiencia.
La aplicación mas típica para comparar la eficiencia de estos dos algoritmos son loa algoritmos de ordenamiento.
A continuación se muestra el código en Python del algoritmo MergeSort que ordena una lista de 1,000,000 números enteros y luego compara el tiempo de ejecución entre el ordenamiento secuencial y el ordenamiento en paralelo.
import random
import time
import multiprocessing
# Función para dividir una lista en dos mitades
def split_list(arr):
mid = len(arr) // 2
return arr[:mid], arr[mid:]
# Función para combinar dos listas ordenadas
def merge(left, right):
result = []
i = j = 0
while i < len(left) and j < len(right):
if left[i] < right[j]:
result.append(left[i])
i += 1
else:
result.append(right[j])
j += 1
result.extend(left[i:])
result.extend(right[j:])
return result
# Función de ordenamiento Merge Sort
def merge_sort(arr):
if len(arr) <= 1:
return arr
left, right = split_list(arr)
left = merge_sort(left)
right = merge_sort(right)
return merge(left, right)
# Función de ordenamiento paralelo utilizando multiprocessing
def parallel_merge_sort(arr):
if len(arr) <= 1:
return arr
left, right = split_list(arr)
# Procesos para ordenar las mitades en paralelo
with multiprocessing.Pool(2) as pool:
left = pool.apply(merge_sort, [left])
right = pool.apply(merge_sort, [right])
return merge(left, right)
if __name__ == "__main__":
# Generar una lista aleatoria de números
random.seed(42)
arr = [random.randint(0, 1000) for _ in range(10000)]
# Medir el tiempo para el ordenamiento secuencial
start_time = time.time()
sorted_arr_seq = merge_sort(arr)
seq_time = time.time() - start_time
# Medir el tiempo para el ordenamiento en paralelo
start_time = time.time()
sorted_arr_parallel = parallel_merge_sort(arr)
parallel_time = time.time() - start_time
print("Tiempo de ejecución secuencial:", seq_time)
print("Tiempo de ejecución en paralelo:", parallel_time)
Resultado:
Tiempo de ejecución secuencial: 5.5400121212005615
Tiempo de ejecución en paralelo: 10.639057397842407
Ahora se realizara para una lista de 10,00,000 elementos.
Resultado:
Tiempo de ejecución secuencial: 62.5855598449707
Tiempo de ejecución en paralelo: 62.20775890350342
Conclusiones.
Aunque la programación en paralelo tiene el potencial de acelerar la ejecución de tareas, hay ciertas operaciones adicionales que se deben realizar cuando se trabajan con procesos en paralelo. En este caso, la creación y coordinación de procesos adicionales introducen una sobrecarga significativa que puede hacer que la ejecución en paralelo sea más lenta que la ejecución secuencial, especialmente cuando el tamaño del problema (en este caso, el tamaño de la lista que se está ordenando) no es lo suficientemente grande como para compensar esta sobrecarga.
En resumen, en situaciones donde el tamaño del problema es pequeño o la sobrecarga de coordinación es significativa, la ejecución secuencial puede ser más eficiente en términos de tiempo de ejecución que la ejecución en paralelo. Es importante tener en cuenta estos factores al decidir entre programación secuencial y paralela.