Publicado el 30 de Julio del 2018
1.073 visualizaciones desde el 30 de Julio del 2018
493,6 KB
42 paginas
Creado hace 8a (28/10/2016)
Programación en Intel® Xeon Phi™
Programación en Intel® Xeon Phi™
David Corbalán Navarro
David Corbalán Navarro
Máster en Nuevas Tecnologías de la Informática
Máster en Nuevas Tecnologías de la Informática
Índice
Índice
● Introducción al paralelismo
● Niveles de paralelismo
● Paradigmas de programación paralela
● Manycores
● Intel® Xeon Phi™
● Programación
● Monitorización y control
● Conclusiones
● Referencias bibliográficas
22
Índice
Índice
● Introducción al paralelismo
● Niveles de paralelismo
● Paradigmas de programación paralela
● Manycores
● Intel® Xeon Phi™
● Programación
● Monitorización y control
● Conclusiones
● Referencias bibliográficas
33
Introducción al paralelismo
Introducción al paralelismo
● Los primeros monocores
● Límite de frecuencia de operación
→
Explotar el ILP:
– Pipeline escalares segmentados
– Superescalares
– Ejecución fuera de orden
– Ejecución especulativa
– …
● La carrera del gigahercio
● Los primeros multiprocesadores
– Nuevo horizonte: paralelismo inter-proceso
– Ahora el límite está en el aprovechamiento de los procesadores
● Manycores
GPGPU
→
44
Índice
Índice
● Introducción al paralelismo
● Niveles de paralelismo
● Paradigmas de programación paralela
● Manycores
● Intel® Xeon Phi™
● Programación
● Monitorización y control
● Conclusiones
● Referencias bibliográficas
55
Niveles de paralelismo
Niveles de paralelismo
● ILP (Instruction Level Paralelism)
– Grano muy fino
– Estático: el compilador (SW) explota el ILP
– Dinámico: el propio HW explota el ILP
→
● SIMD (Single Instruction Multiple Data)
VLIW→
superescalares
– Operaciones masivas en datos
– Procesadores vectoriales: MMX, SSE, SSE2, SSE3, AVX…
● MIMD (Multiple Instruction Multiple Data)
● SIMT (Single Instruction Multiple Threads)
– Paralelismo a nivel de hilo/proceso/nodo
– Aparece el concepto de sincronización (entre hilos)
66
Índice
Índice
● Introducción al paralelismo
● Niveles de paralelismo
● Paradigmas de programación paralela
● Manycores
● Intel® Xeon Phi™
● Programación
● Monitorización y control
● Conclusiones
● Referencias bibliográficas
77
Paradigmas de programación
Paradigmas de programación
paralela
paralela
● Memoria compartida:
– Elementos de cómputo: hilos
– Todos los hilos comparten la misma memoria
– Se comunican mediante sincronizaciones
– Adecuado para su uso en procesadores multicore
– Ejemplo extendido: OpenMP
● Paso de Mensajes:
– Elementos de cómputo: procesos/nodos
– Cada nodo tiene control sobre una porción de memoria determinada
– Se comunican mediante mensajes
– Adecuado para su uso en clústers
– Ejemplo extendido: MPI
→
● Generalmente se combinan
programación híbrida: OpenMP+MPI
– Motivación: un procesador puede integrar muchos cores, pero… ¡muchos computadores
pueden integrar muchos procesadores multicore!
88
Índice
Índice
● Introducción al paralelismo
● Niveles de paralelismo
● Paradigmas de programación paralela
● Manycores
● Intel® Xeon Phi™
● Programación
● Monitorización y control
● Conclusiones
● Referencias bibliográficas
99
Manycores
Manycores
● Aceleradores gráficos
● Gran cantidad de cores pequeños implementados
en el mismo procesador
● Lanzamiento de hilos poco costoso
● Procesamiento masivo en datos
● Ejemplos comerciales:
– Nvidia: CUDA y OpenCL
– Intel® Xeon Phi™: Xeon Phi™ y OpenCL
1010
Índice
Índice
● Introducción al paralelismo
● Niveles de paralelismo
● Paradigmas de programación paralela
● Manycores
● Intel® Xeon Phi™
● Programación
● Monitorización y control
● Conclusiones
● Referencias bibliográficas
1111
Intel® Xeon Phi™
Intel® Xeon Phi™
intel.com
1212
Intel® Xeon Phi™
Intel® Xeon Phi™
● Arquitectura
– Host: procesador principal
– Dispositivos: aceleradores denominados MIC (Many
Integrated Core)
– Bus PCI-express: interfaz que conecta el host con los
dispositivos
● Los dispositivos ejecutan su propio núcleo del
sistema operativo (Linux)
● Posibilidad de conexión mediante ssh
1313
Intel® Xeon Phi™
Intel® Xeon Phi™
intel.com
1414
Intel® Xeon Phi™
Intel® Xeon Phi™
● Manycore
● Paralelismo SIMT
● Memoria compartida: dentro del propio dispositivo
● Paso de mensajes: transferencia de datos entre el
host y los dispositivos
1515
Índice
Índice
● Introducción al paralelismo
● Niveles de paralelismo
● Paradigmas de programación paralela
● Manycores
● Intel® Xeon Phi™
● Programación
● Monitorización y control
● Conclusiones
● Referencias bibliográficas
1616
Programación
Programación
● Relativamente sencilla (si la comparamos con CUDA y
OpenCL)
● Imprescindible el compilador de Intel: icc
● No precisa de funciones dedicadas, ni de librerías
externas… sólo pragmas
● Se programa en OpenMP, y se añade algo más (lo
veremos más adelante)
● El runtime hace compatible el uso de código tanto para
dispositivos Intel® Xeon Phi™ como para procesadores
convencionales (se ignoran los pragmas y punto)
1717
Programación
Programación
● Es necesario ejecutar antes:
– source /opt/intel/composer_xe_2015/bin/compilervars.sh intel64
– Intel64 es la arquitectura del host
● Para compilar xeon.c:
– icc -o xeon -openmp xeon.c
● Se ha ejecutado todo en Venus
1818
Ejemplo: conteo de cores
Ejemplo: conteo de cores
● Forma tradicional de contar procesadores:
int np = omp_get_num_procs();
printf("Número de procesadores en el host: %d\n", np);
– Resultado:
Número de procesadores en el host: 12
● Con Xeon Phi
int np_mic;
#pragma offload target(mic)
printf("Número de procesadores en la Xeon Phi: %d\n", np_mic);
np_mic = omp_get_num_procs();
– Resultado:
Número de procesadores en la Xeon Phi: 224
1919
Modelos offload
Modelos offload
● Offload explícito
● Offload implícito
● Offload automático
2020
Offload explícito
Offload explícito
● La sincronización entre los hilos y las transferencias
entre host y dispositivos se hace de manera
explícita mediante transferencias de memoria y
primitivas de sincronización
● Abstracción baja
● Control alto de la arquitectura
● Pragma principal:
#pragma offload target(mic[:dev])
2121
Offload explícito
Offload explícito
● Procedimiento:
(1)Reservar memoria en el MIC
(2)Copiar desde el host hacia el MIC
(3)Computar
(4)Copiar desde el MIC hacia el HOST
(5)Liberar memoria en el MIC
2222
Offload explícito
Offload explícito
__declspec(align(64))
1000000
#define ALIGN
#define VECTOR_SIZE
ALIGN float v1[VECTOR_SIZE];
ALIGN float v2[VECTOR_SIZE];
initArray(v1, VECTOR_SIZE);
initArray(v2, VECTOR_SIZE);
float prodesc = 0.0;
#pragma offload target(mic)
{
#pragma omp parallel for private(i) reduction(+:prodesc)
for (i = 0; i < VECTOR_SIZE; i++)
prodesc += v1[i] * v2[i];
}
printf("Resultado: %.2f\n", prodesc);
2323
Offload explícito
Offload explícito
● Arrays dinámicos
posix_memalign((void**) &v1, 64, sizeof(float) * VECTOR_SIZE);
posix_memalign((void**) &v2, 64, sizeof(float) * VECTOR_SIZE);
initArray(v1, VECTOR_SIZE);
initArray(v2, VECTOR_SIZE);
...
#pragma offload target(mic) in(v1, v2 : length(VECTOR_SIZE))
{
prodesc = 0.0;
#pragma omp parallel for private(i) reduction(+:prodesc)
for (i = 0; i < VECTOR_SIZE; i++)
prodesc += v1[i] * v2[i];
}
printf("Resultado: %.2f\n", prodesc);
2424
Offload explícito
Offload explícito
● Arrays dinámicos:
– La memoria se reserva alineada a 64 bits por motivos de
rendimiento
– Tamaño explícito de los vectores de memoria: el MIC no
conoce, a priori, la memoria que tiene que copiar
– Transferencias:
→
transferencia implícita de host a MIC
● in: datos de entrada
→
● out: datos de salida
transferencia implícita de MIC a host
● inout: datos de entrada y salida
transferencias implícitas entre
host y MIC
→
● nocopy: datos internos del dispositivo
2525
Offload explícito
Offload explícito
● Ejecución selectiva: podemos decidir en qué MIC
queremos que se ejecute el pragma:
#pragma offload target(mic:0) in(v1, v2 : length(VECTOR_SIZE))
{
prodesc = 0.0;
#pragma omp parallel for private(i) reduction(+:prodesc)
for (i = 0; i < VECTOR_SIZE; i++)
prodesc += v1[i] * v2[i];
}
2626
Offload explícito
Offload explícito
● Funciones en dispositivo
#define DEVICE
DEVICE int suma_vector(int * v, int n)
{
__declspec(target(mic))
int i;
int tmp = 0;
for (i = 0; i < n; i++)
tmp += v[i];
return tmp;
}
...
int n_vector = 8;
int * vector = (int *) malloc(sizeof(int) * n_vector);
int result;
#pragma offload target(mic) in(vector : length(n_vector))
result = suma_vector(vector, n_vector);
printf("Resultado de la suma: %d\n", result);
2727
Offload explícito
Offload explícito
● Transferencias explícitas
#define ALLOC
#define FREE
#define RETAIN
#define REUSE
...
#pragma offload_transfer target(mic) in(v1, v2 : length(VECTOR_SIZE) ALLOC RETAIN)
#pragma offload target(mic) nocopy(v1, v2 : length(VECTOR_SIZE) REUSE FREE)
{
alloc_if(1)
free_if(1)
free_if(0)
alloc_if(0)
prodesc = 0.0;
#pragma omp parallel for private(i) reduction(+:prodesc)
for (i = 0; i < VECTOR_SIZE; i++)
prodesc += v1[i] * v2[i];
}
2828
Offload explícito
Offload explícito
● Ejecución asíncrona (barrera implícita)
int barrier = 1;
#pragma offload_transfer target(mic:0) in(v1, v2 : length(VECTOR_SIZE) ALLOC RETAIN)
signal(&barrier)
<Computación solapada con la copia de host a MIC>
#pragma offload target(mic:0) nocopy(v1, v2 : length(VECTOR_SIZE) REUSE FREE)
{
wait(&barrier)
prodesc = 0.0;
#pragma omp parallel for private(i) reduction(+:prodesc)
for (i = 0; i < VECTOR_SIZE; i++)
prodesc += v1[i] * v2[i];
}
¡Es necesario indicar el MIC al que va dirigido el evento!
2929
Offload explícito
Offload explícito
● Ejecución asíncrona (barrera explícita)
int barrier = 1;
#pragma offload_transfer target(mic:0) in(v1, v2 : length(VECTOR_SIZE) ALLOC RETAIN)
signal(&barrier)
<Computación solapada con la copia de host a MIC>
#pragma offload_wait target(mic:0) wait(&barrier)
#pragma offload target(mic:0) nocopy(v1, v2 : length(VECTOR_SIZE) REUSE FREE)
{
prodesc = 0.0;
#pragma omp parallel for privat
Comentarios de: Programación en Intel Xeon Phi (0)
No hay comentarios