Rendimiento Aplicado a programas openMP. Speedup Speedup = t s /t p donde t s es el tiempo que se...

Post on 28-Jan-2016

222 views 0 download

Transcript of Rendimiento Aplicado a programas openMP. Speedup Speedup = t s /t p donde t s es el tiempo que se...

Rendimiento

Aplicado a programas openMP

Speedup

• Speedup = ts /tp donde ts es el tiempo que se requiere para ejecutar el programa secuencialmente y tp es el tiempo que se requiere para ejecutar el programa en paralelo

• El autor del texto denota speedup por ψ(n,p) donde n es el tamaño del problema y p es el número de procesos

Speedup (cont)

– ψ(n,p)≤p

– ψ(n,p)=p si el problema se particiona perfectamente en p procesos iguales y no hay ningun “overhead” debido a, por ejemplo, comunicaciones, coordenació de procesos, el costo de particionar, etc.

omp_get_wtime

Esta función devuelve un valor en punto flotante doble igual al tiempo que ha transcurrido desde algun tiempo en el pasado.

Se puede medir el tiempo que tarda un como sigue:

empezar = omp_get_wtime; // aqui va el código cuyo tiempo de ejecutación se desea medir

final = omp_get_wtime;

tiempo = final – empezar;

Medir el tiempo para aproximar π

// Entramos el numero de hilos desde la linea de comando#include <omp.h> #include <stdio.h>#include<time.h>#include<sys/time.h> int main (int argc, char *argv[]) { double area,x,start,end; int i,n; area = 0.0;printf("n=");scanf("%d",&n);

Medir tiempo de aproximar π (cont)

omp_set_num_threads(atoi(argv[1]));start=omp_get_wtime;#pragma omp parallel for private(x) reduction(+:area);for (i=0;i<n;i++) { x=(i+0.5)/n; area += 4.0/(1.0+x*x);}end=omp_get_wtime;printf(“tiempo=%lf\n”,end-start);printf("pi = %lf\n", area/n);return 0; }

Algunos trucos para mejorar rendimiento

• Invertir bucles

• Ejecutar bucles condicionalmente

• Usar la cláusula schedule

Mejormiento en Rendimiento Invertiendo Bucles

• Muchos fork/joins puede empeorar el rendimiento

• Invertir bucles puede mejorar el rendimiento si– Hay paralelismo en el bucle interio– El bucle exterior se puede paralelizar

después de la inversión.– La inversión no disminuye la razón de

“cache hits”

Ejemplo 1

for (j=2;j<n;j++)

for (i=1;i<n;i++)

a[i][j] = a[i][j]+a[i][j-1]];

Lo mejor es paralelizar el bucle exterior, pero en este caso hay dependencias.l

Ejemplo 1 (cont)

Se puede invertir los bucles:

#omp parallel for

for (i=1;i<n;i++)

for (j=2; j<n;j++)

a[i][j] = a[i][j]+a[i][j-1]];

Aqui hemos reducido los gastos de paralelizar, pero el nuevo bulce podria utilizar peor el cache.

Ejemplo 2

Intercambiando los bulces enfor (i=2;i<=m;i++) for (j=1;j<=n;j++) a[i][j] = 2*a[i][j];tenemos#pragma parallel for private(i)for(j=1;j<=n;j++) for(i=2;i<=m;i++) a[i][j] = 2*a[i][j];(columnas se pueden poner al dia simultaneamente – no

filas)

Mejormiento en Rendimiento Ejecutando Bucles Condicionalmente

• Si un bucle tiene pocas iteraciones, los gastos generales podría ser mayor que la economia de ejecutación paralela.

• La cláusula if instruye al compilador determinar si el bucle se debe ejecutar en paralelo.

#pragma omp parallel for if(n > 5000)

Mejormiento en Rendimiento usando la cláusula schedule

• Las iteraciones de un bucles pueden variar mucho en duración.

• Se puede usar una cláusula schedule para indicar como las iteraciones se asignan a los hilos.

Ejemplo

for (i=0;i<n;i++)

for (j=i;j<n;j++)

a[i][j] = alpha_omega(i,j);

Si toda iteraciión requiere el mismo tiempo, entonces el tiempo que requiere la primera iteración es n veces del tiempo que requiere la ultima iteraciión.

Estático vs. Dinámico

• Schedule estática: todas las iteraciones se asignan a los hilos antes de ejecutarla

• Schedule dinámica: solamente algunas iteraciones se asignan al prinicipio de la ejecutación de un bucle. Las otras iteraciones se asignan a hilos que terminan sus iteraciones asignadas.

Estático vs. Dinámico (cont)

• Static scheduling:

• -Gastos generales menores (“low overhead”)

• Dynamic scheduling

– Gastos generales mayores

– Puede reduce el imbalance de trabajo

Chunks

• Un chunk es un conjunto contiguos de iteraciones que se asignan a hilos

• Aumentar el tamaño de un chunk reduce los gastos generales y podría aumentar el “cache hit rate”

• Disminuir el tamaño de chunk permite uno a obtener un balance mas preciso del trabajo

La Cláusula schedule

• La sintaxis:schedule (<tipo>[,<chunk> ])

• Se requiere tipo, pero el tamaño del chunk es opcional

• El tipo puede ser– static– dynamic– guided– runtime

Opciones para schedule

• schedule(static): asignar bloques de aproximadamente n/t iteraciones contiguas a cada hilo

• schedule(static,C): asignar chunks de tamaño C

• schedule(dynamic): asignar dinámicamente iteraciones una por una.

• schedule(dynamic,C): asignar dinámicamente C iteraciones a la vez

Opciones para schedule (cont)

• schedule(guided, C): asignar chunks dinámicamente. Los tamaños de los chunks disminuyen dependiendo de la implementación.

C es el tamaño mínimo.• schedule(guided): Lo mismo excepto 1 es el

tamaño mínimo.• schedule(runtime): el tipo de schedule se

escoge al tiempo de ejecutación basado en el

valor de la variable omp_schedule.

El ejemplo anterior con schedule

#pragma omp parallel for private(j) schedule(static,1)

for (i=0;i<n;i++)

for (j=i;j<n;j++)

a[i][j] = alpha_omega(i,j)

Se podria aumentar el tamaño de chunk para mejorar la razón de “cache hits”, al costo de aumentar el imbalance de trabajo de los hilos.

Mas sobre speedup

Los componentes de tiempo de ejecutación:

- Computaciones que tienen que hacer secuencialmente: (n)

- Computaciones que se pueden llevar a cabo en paralelo: (n)

- Operaciones de comunicaciones: (n,p)

Expresión para Speedup

• ts = (n) + (n)

• tp = (n) + (n)/p + (n,p)

• Por lo tanto,

ψ(n,p) ≤ ((n) + (n))/((n) + (n)/p + (n,p))

(n)/p

• Aumentar el número de procesadores reduce el tiempo computacional

(n)/p

(n,p)

• El tiempo de comunicaciones crece con la cantidad de procesadores

(n,p)

• En algun momento el tiempo de comunicaciones será mayor que el tiempo computacional

(n)/p + (n,p)

(n)/p + (n,p)

Speedup

Eficiencia

• Eficiencia = tS / (p*tp) donde p es el número de procesadores

• Ya que tp ≤ tS / p, tenemos que

0 ≤ Eficiencia ≤ 1

• El autor denota eficiencia por (n,p)• Notemos que (n,p)=ψ(n,p)/p

La Ley de Amdahl

ψ(n,p) ≤ ((n) + (n))/((n) + (n)/p + (n,p))

≤ ((n) + (n))/((n) + (n)/p )La Ley de Amdahl: Si f es la porción de la

computación que es inherentemente secuencial, es decir que f=(n)/((n) + (n)), entonces

ψ ≤ 1/(f+(1-f)/p)

Notemos que ψ ≤ 1/f

Ejemplo 1

• Hay un programa secuencial que pasa 90% de su tiempo dentro de funciones que se pueden paralelizar. Hay que hacer el otro 10% en un solo procesador. ¿Vale la pena implantar una versión paralela si

hay 8 procesadores disponibles?• ψ ≤ 1/(f+(1-f)/p)=1/(.1 + (1-.1)/8) = 4.7

• El máximo speedup posible es lim p →∞ 1/(.1 + (1-.1)/p) = 10

Pop Quiz

• A computer animation program generates a feature movie frame-by-frame. Each frame can be generated independently and is output to its own file. If it takes 99 seconds to render a frame and 1 second to output it, how much speedup can be achieved by rendering the movie on 100 processors?