Documentos de Académico
Documentos de Profesional
Documentos de Cultura
1/37
Contenido
Contenido
Cmputo en paralelo
Operaciones matemticas en paralelo
Evolucin de los procesadores de propsito general
El cache
El esquema OpenMP
Prdida de eficiencia con el aumento de procesadores
Post data: Optimizar el cdigo compilado
Preguntas?
Para saber ms...
17/08/11
2/37
1E+10
1970
3E+10
1975
1985
1990
17/08/11
1995
6E+10
5E+10
4E+10
2000
8E+10
2005
Intel Core i7
AMD Phenom II X4 (76G ips)
(43G ips)
Intel Core 2
(49G ips)
7E+10
PlayStation 3 Cell
(10G ips)
Motorola 68040
(44M ips)
Intel 80x486
(54M ips)
Motorola 68060
(88M ips)
Intel Pentium Pro
(541M ips)
0E+0
Intel 80x386
(11M ips)
1980
Intel 80x286
(4M ips)
Motorola 68000
(1M ips)
Intel 8080
(500K ips)
Intel 4004
(92K ips)
Cmputo en paralelo
Cmputo en paralelo
2010
procesadores
multi-core
3/37
Cmputo en paralelo
Algoritmo
en
paralelo
Algoritmo
en
serie
4/37
a= x i y i,
i=1
donde a es un escalar, una primera aproximacin sera verlo como una secuencia de sumas de
productos que requieren irse acumulando, al verlo as no es una operacin paralelizable.
17/08/11
5/37
x2 y2
x3 y3
a= x i y i
x4 y4
x5 y 5
x6 y6
x7 y7
x8 y8
x9 y9
...
xn yn
...
i=1
...
+
a
En este caso se tiene una paralelizacin eficiente de la multiplicacin de las entradas de los
vectores, despus se va reduciendo la eficiencia. Muchos algoritmos seriales requieren, para ser
paralelizados, de re-ordenar las operaciones con una estrategia de divide y vencers, como en
el caso del producto punto.
17/08/11
6/37
Usualmente se tendrn memos procesadores que el tamao del vector, por lo que se asignan
varias operaciones de un grupo a cada procesador, las cuales se ejecutarn en secuencia, lo que
limita la eficiencia del paralelismo.
x1 y1
N
a= x i y i
x2 y 2
x3 y3
x4 y4
x5 y5
x6 y6
x7 y7
+
x 8 y8
x9 y9
...
xn yn
...
i=1
+
a
17/08/11
7/37
Running program
Heap
Processor
Bus
Bus
RAM
Stack
Code
Data
Desde un punto de vista fsico muy simplificado, la computadora contiene un procesador (CPU)
que accesa a la memoria (RAM) a travs de un bus de datos/direcciones.
La velocidad de los procesadores y la memoria (RAM) era equivalente.
Desde el punto de vista de la ejecucin de un programa, la memoria est dividida en Heap (o
montculo), Stack (pila) donde se almacenan las variables declaradas dentro de una funcin y
Data (regin donde se almacenan las variables globales).
17/08/11
8/37
Running program
Processor
Cache
Heap
Bus
Bus
RAM
Stack
Data
Code
Thread
Stack
Thread
Stack
Thread
Stack
9/37
El cache
El cache
La velocidad de operacin de los procesadores es mucho mayor que la velocidad de acceso de la
memoria RAM de las computadoras [Wulf95], esto es debido a que es muy costoso fabricar
memoria de alta velocidad.
Para solventar esta diferencia en velocidad, los procesadores modernos incluyen memoria cache,
en diferentes niveles (L1, L2 y en algunos casos L3). Estas memoria cache son de alta velocidad
aunque de menor capacidad que la memoria RAM del sistema. Su funcin es la de leer de forma
anticipada memoria RAM mientras el core est trabajando y modificar la informacin leida de
forma local. Cuando entra nueva informacin al cache la informacin ya procesada es
almacenada en la memoria RAM.
La siguiente tabla muestra los ciclos de reloj de CPU necesarios para accesar cada tipo de
memoria en un procesador Pentium M:
Acceso a
Registro CPU
L1
L2
Memoria RAM
Ciclos
1
~3
~ 14
~ 240
10/37
El cache
Para trabajar eficientemente con el cache es necesario que los datos con los cual trabaja el
programa sean puestos de forma continua en la memoria RAM. Las variables deben ser
declaradas dentro de la funcin en la cual sern utilizados, as estas estarn almacenados en el
stack, lo cual facilitar que caigan en el cache L1 [Fog10].
#define S 2000
Heap
a[]
int i;
double* a = (double*)malloc(S*sizeof(double));
void funcion(void)
{
double b[S];
for (i = 0; i < S; ++i)
b[i] = i*2.0;
for (int j = 0; j < S; ++j) {
b[j] += a[j];
a[j] = 0;
}
Stack
b, b[], j
Data
i, a
}
El programa anterior accesa localidades de memoria distantes.
17/08/11
11/37
El cache
El cache lee la memora RAM en por lneas o bloques de N bytes contiguos (N ~ 64). Los
circutos del cache estn diseados para hacer esta lectura de forma mucho ms rpida que
haciendo lecturas a regiones no contiguas.
Una lnea de cache se accesa ms rpido si se la lee de forma secuencial hacia adelante (i++).
Leerlo en forma inversa es un poco ms lento (i--).
17/08/11
12/37
El cache
#include <stdio.h>
int main(void)
{
char* A = new char[ROWS*COLS];
int main(void)
{
char* A = new char[ROWS*COLS];
delete [] A;
delete [] A;
return 0;
return 0;
126.760s
6.757s
13/37
El cache
L1
L1
Core 2
Core 3
L1
Processor
Core 1
Cache L2
Bus
Bus
RAM
Heap
17/08/11
Thread
Core 1
Stack
Para reducir sta latencia se le ha agregado otro nivel
de cache, llamado L2.
Code
Data
Thread
Core 2
Thread
Core 3
Stack
Stack
Stack
14/37
El cache
Core 2
Core 3
Cache L2
L1
Processor
Core 1
L1
Multi-core computer
L1
Bus
Bus
RAM
Mantener coherencia en la informacin cuando varios cores accesan la misma memoria RAM es
complejo. Los detalles se pueden consultar en [Drep07].
17/08/11
15/37
El cache
17/08/11
16/37
El cache
Multi-processor computer
Core 6
Code
Thread
Core 1
Cache
coherence
RAM
Stack
Data
Thread
Core 2
Thread
Core 3
Thread
Core 4
RAM
Thread
Core 5
Thread
L1
Core 5
L1
L1
Processor 2
Core 4
Cache L2
L1
Core 3
Heap
Cache L2
Core 2
L1
L1
Processor 1
Core 1
Running program
Core 6
17/08/11
Stack
Stack
Stack
Stack
Stack
Stack
17/37
El esquema OpenMP
El esquema OpenMP
Sirve para paralelizar programas en C, C++ o Fortran en computadoras multi-core o
multi-thread.
Busca que escribir cdigo en paralelo sea sencillo.
Es un esquema de paralelizacin con memoria compartida (todos los procesadores accesan a la
misma memoria).
Su funcionamiento interno es con threads, en el caso de sistemas POSIX se utiliza la librera de
POSIX-Threads (libpthread).
Algunos compiladores que soportan este esquema:
GNU Compiler Collection GCC (versin >= 4.3.2)
Intel Compiler Suite (version >= 10.1)
Microsoft Visual Studio 2008 (Professional)
Microsoft Visual Studio 2008 (Express) + Windows SDK for Windows Server 2008
La lista completa: http://openmp.org/wp/openmp-compilers
17/08/11
18/37
El esquema OpenMP
Procesamiento
serial
Core 1
Core 2
Thread
inactivo
Core 3
Core 4
Thread
activo
Core n
Creacin de
los threads
Sincronizacin
17/08/11
19/37
El esquema OpenMP
La paralelizacin sera...
17/08/11
20/37
El esquema OpenMP
En Visual C++ hay una opcin en las preferencias del proyecto para activar OpenMP.
17/08/11
21/37
El esquema OpenMP
Cmo funciona?
Supongamos que size = 30, si la computadora tiene 3 procesadores, el cdigo se ejecutara como:
void Suma(double* a, double* b, double* c, int size)
{
#pragma omp parallel for
for (int i = 0; i < 10; ++i) for (int i = 10; i < 20; ++i) for (int i = 20; i < 30; ++i)
{
{
{
c[i] = a[i] + b[i];
c[i] = a[i] + b[i];
c[i] = a[i] + b[i];
}
}
}
}
17/08/11
22/37
El esquema OpenMP
En Windows:
set OMP_NUM_THREADS=3
programa.exe
17/08/11
23/37
El esquema OpenMP
17/08/11
24/37
El esquema OpenMP
Reducciones
El ejemplo que mostraremos es el producto punto:
double ProductoPunto(double* a, double* b, int size)
{
double c = 0;
for (int i = 0; i < size; ++i)
c += a[i]*b[i];
return c;
}
Su paralelizacin sera:
double ProductoPunto(double* a, double* b, int size)
{
double c = 0;
#pragma omp parallel for reduction(+:c)
for (int i = 0; i < size; ++i)
c += a[i]*b[i];
return c;
}
17/08/11
25/37
El esquema OpenMP
17/08/11
26/37
El esquema OpenMP
17/08/11
27/37
El esquema OpenMP
OpenMP hace considera a y b como variables compartidas (shared), es decir, todos los threads
las pueden accesar y modificar.
Para las variables del ciclo i y de la reduccin c, OpenMP hace un copias de las variables al stack
de cada thread, con lo cual se convierten a privadas (private). Al terminar se sumarn las c de
cada thread en la variable c que ahora se considerar shared.
Adems, todas las variables declaradas dentro del bloque parallel sern privadas.
Tambin es posible decidir de forma explcita que variables queremos que tengan un
comportamiento privado o shared.
17/08/11
28/37
El esquema OpenMP
17/08/11
29/37
El esquema OpenMP
Schedule
Por default, al paralelizar un ciclo el nmero de iteraciones se divide por igual entre cada thread.
Sin embargo, esto no es eficiente si las iteraciones tardan tiempos diferentes en ejecutarse.
Es posible hacer entonces reajustar la distribucin de iteraciones de forma dinmica, esto se hace
con schedule.
#pragma omp parallel for schedule(type[, chunk_size])
for (int i = 0; i < size; ++i)
{
c[i] = a[i] + b[i];
}
30/37
El esquema OpenMP
Otro ejemplo
Ahora veamos la multiplicacin matriz-vector:
void Mult(double* A, double* x, double* y, int rows, int cols)
{
#pragma omp parallel for
for (int i = 0; i < rows; ++i)
{
double sum = 0;
for (int k = 0; k < cols; ++k)
{
sum += A[i*cols + k]*x[k];
}
y[i] = sum;
}
}
Hay que notar que las operaciones no se interfieren, dado que cada iteracin slo escribe en el
elemento y[i].
17/08/11
31/37
El esquema OpenMP
Secciones crticas
#pragma omp critical
{
mpi.Send(p, tag_x, x);
}
17/08/11
32/37
Tiempo [m]
15.00
10.00
5.00
0.00
1
10
11
12
13
14
15
16
Procesadores
Sea t 1 el tiempo real que tard el resolverse un problema con un core, n el nmero de
procesadores utilizado, el tiempo ideal de ejecucin lo podemos definir como
t1
i n= .
n
17/08/11
33/37
Eficiencia
0.60
0.50
0.40
0.30
0.20
0.10
0.00
1
10
11
12
13
14
15
16
Procesadores
17/08/11
34/37
17/08/11
35/37
Preguntas?
Preguntas?
17/08/11
36/37
Bibliografa:
[Chap08] B. Chapman, G. Jost, R. van der Pas. Using OpenMP: Portable Shared Memory
Parallel Programming. The MIT Press, 2008.
[Drep07] U. Drepper. What Every Programmer Should Know About Memory. Red Hat, Inc.
2007.
[Fog10] A. Fog. Optimizing software in C++. An optimization guide for Windows, Linux and
Mac platforms. Copenhagen University College of Engineering. 2010.
[Wulf95] W. A. Wulf , S. A. Mckee. Hitting the Memory Wall: Implications of the Obvious.
Computer Architecture News, 23(1):20-24, March 1995.
17/08/11
37/37