De vuelta en Cork, y después de unas primeras semanas un poco ajetreadas por el trabajo, me decidí a probar cómo funciona el Core 2 Duo bajo una implementación en paralelo, es decir, ejecutando dos procesos distintos al mismo tiempo, un proceso por núcleo del procesador.
La estructura básica de un procesador de doble núcleo es la siguiente:
Cada núcleo dispone de su propia memoria caché de primer nivel (L1) y comparten la caché de segundo nivel (L2) además de la RAM, claro está.
Lo más eficiente (y fácil) para programar en paralelo intra-nodo es usar el estándar OpenMP. Intra-nodo quiere decir que se comunican procesos que tienen lugar dentro de núcleos que comparten la misma memoria física. Creo recordar que el nodo con mayor número de núcleos disponible comercialmente es uno con 16. El mío, como ya he comentado, tiene dos núcleos.
Para acceder a un mayor número de procesadores es necesario conectarlos en una red local, para lo cual se puede utilizar, por ejemplo, el estándar MPI.
A la hora de paralelizar una operación hay que plantearse si es de hecho más eficiente hacerlo en paralelo o es mejor en serie (usando sólo uno de los núcleos). La implementación en paralelo es siempre más eficiente dadas dos condiciones:
1. Que el problema a resolver puede separarse en varios procesos totalmente independientes entre sí.
2. Que la complejidad del problema compensa el tiempo que se pierde al tener varios núcleos accediendo a la misma memoria a la vez.
De hecho, aunque se dé la primera circunstancia, si el problema es muy simple puede ocurrir que, debido al uso de memoria de la implementación en paralelo, un sólo núcleo haga el trabajo completo más rápido que dos núcleos haciendo la mitad del trabajo cada uno.
Así que programé una rutina en FORTRAN que resolvía las siguientes integrales de funciones cada vez más difíciles de computar:
La más fácil:
\int_0^{\pi} sin(x) \text{d}x
\int_0^{\pi} sin(x) cos(x) \text{d}x
\int_0^{\pi} sin {\left[ sin(x) cos(x) \right]} \text{d}x
Se observa que, a medida que aumenta la complejidad del problema, el proceso en paralelo (que consistió en que cada núcleo resolviera la mitad de la integral) es más y más eficiente que el proceso en serie.
El código que programé se puede descargar aquí. Quien lo quiera ejecutar en Linux puede hacer lo siguiente:
sudo apt-get install f95 (si no tienes el compilador instalado)
cd /directorio_donde_hayas_puesto_el_código/
f95 -fopenmp -o test.ex test.f (compila el código y crea un ejecutable)
./test.ex (ejecuta el programa)