• No se han encontrado resultados

La matriz ampliada A B es:

N/A
N/A
Protected

Academic year: 2021

Share "La matriz ampliada A B es:"

Copied!
6
0
0

Texto completo

(1)

SISTEMAS PARALELOS Y DISTRIBUIDOS. 3º GIC. PRÁCTICA 7.

NÚCLEOS MULTIMEDIAS.

1.

OBJETIVOS Y PREPARACIÓN.

En esta práctica vamos a estudiar la optimización de código mediante el uso de las extensiones multimedia o núcleos vectoriales disponibles en los procesadores P4.

La historia de las extensiones multimedia en la familia Intel x86 ha sido resumidamente:

- Comienza con el Pentium MMX (1994), en el que se añadieron un conjunto de 8 registros de 64 bits (2x32 bits) y una serie de instrucciones que permitían el procesado SIMD (Single Instruction Múltiple Data) de datos enteros. Estas extensiones se denominaron MMX.

- El siguiente paso se da en el Pentium III, el cual contiene un conjunto de 8 registros de 128 bits (4x32 bits) y una serie de instrucciones para el procesado SIMD de flotantes en simple precisión. A estas instrucciones se les denomina Streamming SIMD Extensions (SSE).

- Posteriormente, en el P4 se incluyen instrucciones (SSE2 y SSE3) para poder emplear los registros SSE con datos enteros y flotantes de simple o doble precisión (4x32bits o 2x64 bits).

EXPLICACIÓN DE LA APLICACIÓN

Vamos a trabajar con una versión simplificada de una aplicación real que se usa como benchmark en aplicaciones científicas y de multiprocesadores: la resolución de un sistema de ecuaciones lineales mediante el método de eliminación guassiana. De forma genérica, un sistema lineal se expresa como:

Que matricialmente se puede expresar como Ax = B, donde A es la matriz de coeficientes, x el vector de incógnitas y B el vector de coeficientes independientes. Se suele trabajar con la matriz ampliada, que surge de unir A con B (añadiendo una columna más) y se le denomina A|B o simplemente AB.

Para explicar el método, vamos a ver un ejemplo. Sean tres ecuaciones con los siguientes coeficientes:

La matriz ampliada A|B es:

El método debe ir haciendo combinaciones lineales de filas hasta rellenar la matriz triangular inferior de 0’s. Para ello, se elije un “pivote”, que para nosotros siempre será un elemento de la diagonal principal (el 3 con el recuadro, es decir a11). Entonces se multiplica la fila 1 por (- ak1 / a11), y se suma a la fila k para k=2,3,… , es decir, a todas las filas de abajo (segunda y tercera en nuestro ejemplo). Por tanto, ahora AB queda como:

Es decir, ya tenemos la primera columna a 0 (excepto la diagonal principal).

A continuación se repite el proceso pero siendo a22 el pivote (-2 con recuadro), y se consigue un 0 en la segunda columna (para el triángulo inferior):

La solución de las incógnitas se obtiene por sustitución sucesiva hacia atrás. Es decir, primero se despeja xn, después xn-1, (ya que xn es ahora conocido); después xn-2, y así hasta x1. La solución será:

NOTA: en matemáticas se suelen empezar numerando los subíndices por 1, pero en lenguaje C por 0; de manera que nuestro vector de n incógnitas será x0, x1,… xn-1. Similarmente la matriz va desde a00, hasta an-1,n-1.

El esquema de nuestro código es por tanto:

/* Solving an equation linear system by Gaussian elimination to test DLP instructions. More info: http://en.wikipedia.org/wiki/Gaussian_elimination

The process has two parts. The first part (Forward Elimination) reduces a given system to either triangular or echelon form.

(2)

This is accomplished through the use of elementary row operations.

The second step uses back substitution to find the solution of the system above. */

float A_matrix[MAX_RANGE ][MAX_RANGE], B_vector[MAX_RANGE ]; float X_vector[MAX_RANGE ];

void row_processing_C (float *x_0, float *y_0, float a, int first_c, int current_range) {

for (int col=first_c; col<current_range; col++) { y_0[col] = a* x_0[col] + y_0[col];

} }

/* The first part (Forward Elimination) reduces a system to triangular form.*/ void AB_Forward_Elimination (float A[MAX_RANGE ][MAX_RANGE], float B[MAX_RANGE ],

int current_range) { for (int p=0; p<current_range-1; p++) {

for (int row=p+1; row<current_range; row++ ) { float pivot = -A[row][p]/A[p][p];

row_processing_C ( (float*)&A[p][0], (float*)&A[row][0],pivot , 0, current_range);

//last column (the one that belongs to B vector) // is processed out of the function B[row] = pivot * B[p] + B[row] ;

} }

}

Además, la aplicación contiene otras dos funciones similares (no hace falta estudiarlas o preparárselas), para:

AB_back_substitution(): realiza la sustitución sucesiva hacia atrás, para obtener

la solución de las incógnitas.

AB_checker(): es para chequear que el código es correcto; para ello se comprueba

que las incógnitas satisfacen: Ax=B (siendo A,B los valores iniciales del sistema de ecuaciones).

CARACTERÍSTICAS DE LOS PC DE I2.35

Los procesadores del aula I2.35 son (según CPU-Z): - Number of cores 4

- Specification Intel(R) Core(TM) i5 CPU 750 @ 2.67GHz

- Core Speed 2887.9 MHz

- Stock frequency 2666 MHz

- Instructions sets MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, EM64T, VT-x - L1 Data cache 4 x 32 KBytes, 8-way set associative, 64-byte line size - L1 Instruction cache 4 x 32 KBytes, 4-way set associative, 64-byte line size - L2 cache 4 x 256 KBytes, 8-way set associative, 64-byte line size - L3 cache 8 MBytes, 16-way set associative, 64-byte line size

El número de niveles de caché, su tamaño y el tamaño de la línea (bloque) tendrán una influencia muy importante en el rendimiento de las pruebas que haremos en esta práctica.

Tener en cuenta que sólo se usará un core, por tanto, nos centraremos en una sólo cachés (de las 4 que salen indicadas como 4x32, 4x256).

A continuación se presentan las instrucciones IA32 que serán necesarias para la realización de la práctica, con su referencia a “IA32 Intel Architecture Software Developer’s Manual. Volume 2: Instruction Set Reference” (ver p ej: www.cs.utexas.edu/users/dahlin/Classes/UGOS/reading/intelv2.pdf). Nos restringiremos a:

Todos los operandos en registro o memoria con los que trabajaremos serán de 32 bits (o de 128 para registros xmm de 128 bits y accesos multimedia).

NOTACIÓN: r = registro ; m = dirección de memoria. imm = constante inmediata ARITMÉTICAS ENTERAS:

add r/m, r/m/imm[32,16 o 8] (Add – pág 3.21)

lea r, m (Load Effective Address – pág 3.372). Calcula la dirección de m y la almacena en r. Básicamente hace sumas de direccionamientos, pero se usa mucho en x86.

sub r/m, r/m/imm[32,16 o 8] (Subtract – pág 3.729)

cmp r, r/m/imm[32,16 o 8] (CoMPare two operands – pág 3.82)

SALTOS:

jne etiqueta (Jump if Not Equal – pág 3.352) ACCESOS A MEMORIA:

(3)

mov r/m, r/m/imm[32,16 o 8] (Move – pág 3.430). Notas: Ambos operandos deben ser del mismo tamaño. Ambos operandos no pueden referenciar a memoria.

movss xmm/m, xmm/m (Move Scalar Single-precision floating-point values – pág 3.483)

movaps xmm/m128, xmm/m128 (Move Aligned Packed Single-precision floating-point values – pág 3.441)

movntps m128, xmm (Store Packed Single-precision floating-point values using Non-Temporal hint pág 3.471) ARITMÉTICAS MULTIMEDIA:

addps xmm, xmm/m (Add Packed Single-precision floating-point values – pág 3.25)

addss xmm, xmm/m (Add Scalar Single-precision floating-point values – pág 3.29)

mulps xmm,xmm/m128 (Multiply Scalar Single-precision floating-point values – pág 3.496)

mulss xmm, xmm/m (Multiply Scalar Single-precision floating-point values – pág 3.500)

shufps xmm, xmm/m128, imm8 (Shuffle Packed Single-precision floating-point values- pág 3.703)

Como registros de programación se podrá hacer uso de eax, ebx, ecx, edx, esi y edi de 32 bits y xmm0, ... xmm7. NOTA: la instrucción cmp no se debe separar, en general, del salto jne, pues en los x86 hay un bit de estado que guarda el resultado de la última operación aritmética (de forma que si entre cmp y jne hubiese otra instrucción aritmética, tal bit podría ser modificado y perderse el resultado de la comparación).

Antes de acudir al laboratorio el alumno deberá:

- entender cómo está organizado el esquema del código que se proporciona con este enunciado.

- Además, calcular para qué rangos n de la matriz A (A_matrix[MAX_RANGE ][MAX_RANGE] en el código), ésta ocupa completamente las cachés (L1, L2,…). Tales tamaños implicarán los primeros fallos de caché puesto que los vectores x, B etc. También ocupan cierto tamaño en las cachés.

- Hallar los “miss rates” (tasa de fallos) según se pide en la tabla (al final de este enunciado) - Entender el subconjunto de instrucciones multimedia IA32 que se proporcionan.

- Rellenar la parte de preparación de la tabla (al final de este enunciado)

2.

REALIZACIÓN DE LA PRÁCTICA.

En esta prueba, se va a suponer que el rango siempre será N (igual que el número de incógnitas, es decir ninguna fila es combinación lineal de las otras, y por tanto, el sistema va a tener solución única).

Cuando los errores en el chequeo sean grandes (saldrá un mensaje " ***** total quadratic error IS VERY BIG. YOUR CODE MAY BE WRONG ****"), la prueba no sirve y se debe lanzar otra vez.

Abrir el proyecto que se proporciona. Comprobar que las optimizaciones para favorecer código rápido (/Ox /Ot) están activas.

El código tiene tres constantes para compilación condicional, es decir, ciertos fragmentos de código se compilan o no según tales constantes existan. Estos fragmentos son para hacer mediciones o imprimir más valores de tiempos medidos (se explica más adelante). Son:

#define OUTPUT_VALUES

#define COUNTING

#define INNER_TIMER_ACTIVE

Además hay dos constantes para el mayor y menor rango que se va a probar.

#define MAX_RANGE (1024)

#define MIN_RANGE (16)

a. Contando número de llamadas a row_processing_C ().

Dejar sólo definida la constante COUNTING (cambiar el nombre de las otras por ej así)

#define NO_OUTPUT_VALUES

#define COUNTING

#define NO_INNER_TIMER_ACTIVE

Valorar las otras constantes así:

#define MAX_RANGE (1024)

#define MIN_RANGE (16)

Compilar y ejecutar el programa (por ej. “Debug -> Start without debugging” o “ CTRL+F5”.). También puede ejecutar el .exe de la carpeta indicada en propiedades del proyecto (Linker-> Output File, o Enlazador->Archivo de salida).

Anotar los valores de número de llamadas a row_processing_C (valor de counts of AB_Elimination). Rellenar la tabla.

¿Por qué no vale N*N? Chequear que valen

range*(range-1)/2

(4)

b. Anotando tiempos mínimos de AB_Forward_Elimination() en C para diversos rangos de matrices.

No definir ahora ninguna constante (cambiar el nombre por ej así):

#define NO_OUTPUT_VALUES

#define NO_COUNTING

#define NO_INNER_TIMER_ACTIVE

Valorar las otras constantes así:

#define MAX_RANGE (2048)

#define MIN_RANGE (16)

Anotar tiempos mínimos de AB_Forward_Elimination()

c. Anotando tiempos mínimos de AB_Forward_Elimination() con instrucciones ss para diversos rangos de matrices.

Ídem que b pero usando la función row_processing_sse_scalar_float (). Rellenar la tabla. Los tiempos deben salir similares a los de b.

d. Anotando tiempos mínimos de AB_Forward_Elimination() con instrucciones ps para diversos rangos de matrices.

La función row_processing_sse_packed_float () está sin terminar, con objeto de que el alumno sea consciente de los cambios que se necesitan para vectorizar. Todas las líneas con //# deben completarse @

Dado que la mayoría de los errores de asm, conducen a que hay una violación de acceso a memoria, y el S.O. aborta el programa, se recomienda cambiar a configuración Debug, y probar ejecutando paso a paso hasta demostrar que está bien el código.

Cuando le funcione el asm de tal función, proceda igual que b pero con row_processing_sse_packed_float (). Rellenar la tabla.

Razonar por qué los tiempos salen mucho menores en ciertos rangos y aprox. igual para otros. Contestar en la tabla.

e. Anotando tiempos de row_processing_ps () para diversos rangos de matrices.

Dejar sólo definida la constante INNER_TIMER_ACTIVE (cambiar el nombre de las otras por ej así)

#define NO_OUTPUT_VALUES

#define NO_COUNTING

#define INNER_TIMER_ACTIVE

Buscar dentro de AB_Forward_Elimination (), para activar la función row_processing_ps () y quitar las otras row_processing.

Ejecutar y calcular la diferencia relativa entre (valor mínimo y el medio):

- Minimum time in cycles for row_processing

- Mean time in cycles for row_processing

Debería salir parecida puesto que todas las llamadas a row_processing_ps () procesan el mismo número de elementos (siempre habrá fluctuación dependiendo de la carga del PC).

Sin embargo, analizar estos casos y pensar por qué la diferencia relativa entre el valor mínimo y el medio llega a ser tan grande:

- el mayor rango que garantiza que todos los datos A, B, x caben a la vez en la cache L1. - el MENOR rango que garantiza que la matriz A no cabe en ninguna cache.

Calcular finalmente el tiempo mínimo por elemento de la fila procesado (notar que el número de elementos coincide con el rango) y hallar el CPI.

f. Otras preguntas

¿Son paralelizables directamente los bucles centrales de AB_back_substitution() y AB_checker()?

3.

MEMORIA VOLUNTARIA:

Se proponen las siguientes pruebas. Tenga en cuenta que los resultados van a ser muy diferentes con otro procesador, porque podría incluir diferentes optimizaciones en hardware (por ejemplo caché de trazas, prebúsquedas de datos si el patrón de acceso es fácil de adivinar como ocurre en los bucles SAXPY o similares, etc.):

Escribir con código SSE vectorial el bucle central de: AB_back_substitution() y medir tiempos de forma similar a esta práctica (no hacen falta todos los apartados, solo el b, d)

Escribir con código SSE vectorial el bucle central de: AB_checker(),y medir tiempos de forma similar a esta práctica (no hacen falta todos los apartados, solo el b, d).

 Realizar las diferentes pruebas con otra aplicación, concentrándose en la parte del código que llevaría el 90% del tiempo de ejecución o más.

(5)

SPD. PRACTICA 7. NÚCLEOS MULTIMEDIAS.

ALUMNOS:

PREPARACIÓN

¿Qué bucle muy usado en esta asignatura es el de: void row_processing_C ()? Valores de MAX_RANGE

en los cuales la matriz A:

Hallar el MR,L1 (teórico) teniendo en cuenta sólo la función row_processing_C (el resto de código se desprecia) (NOTA: considerar siempre los tres accesos que contiene row_processing_C)

Idem para MR,L2 (teórico)

Cabe en L1:

Cabe en L2:

No cabe en ningún nivel de caché

REALIZACIÓN EN AULA DE ORDENADORES

a. Contando número de llamadas a row_processing_C ().

¿Por qué no vale N*N? Chequear que valen

range*(range-1)/2

b. Anotando tiempos mínimos de AB_Forward_Elimination() en C para diversos rangos de matrices.

c. Anotando tiempos mínimos de AB_Forward_Elimination() con instrucciones ss para diversos rangos de matrices. d. Anotando tiempos mínimos de AB_Forward_Elimination() con instrucciones ps para diversos rangos de matrices.

Ciclos (mínimos) de llamada completa a

AB_Forward_Elimination()

Media de ciclos por cada llamada a row_processing_C ().

Rango Num

llamadas

C ss ps C ss ps Aceleración entre

ps/C

Razonar por qué los tiempos de AB_Forward_Elimination() con instrucciones ps salen mucho menores en ciertos rangos

(6)

Razonar por qué los tiempos de AB_Forward_Elimination() con instrucciones ps salen aprox. igual para otros rangos

¿Por qué cuando el tamaño de la matriz A cabe en el último nivel de caché (los vectores x B son pequeños y no introducen muchos fallos de caché), se da ya un aumento de los ciclos y además los tiempos varían mucho entre diversas ejecuciones (ejecutar varias veces con muchas aplicaciones abiertas en el PC).

e. Anotando tiempos de row_processing_ps () para diversos rangos de matrices. Rango diferencia relativa entre valor

mínimo y medio

Ciclos (mínimos) por elemento de row_processing

CPI (mínimo)

Analizar estos casos y pensar por qué la diferencia relativa entre el valor mínimo y el medio llega a ser tan grande: - el mayor rango que garantiza que todos los datos A, B, x caben a la vez en la cache L1.

- el MENOR rango que garantiza que la matriz A no cabe en ninguna cache.

Referencias

Documento similar

¿Cómo se traduce la incorporación de ésta en la idea de museo?; ¿Es útil un museo si no puede concebirse como un proyecto cultural colectivo?; ¿Cómo puede ayudar el procomún

Primeros ecos de la Revolución griega en España: Alberto Lista y el filohelenismo liberal conservador español 369 Dimitris Miguel Morfakidis Motos.. Palabras de clausura

Tras establecer un programa de trabajo (en el que se fijaban pre- visiones para las reuniones que se pretendían celebrar los posteriores 10 de julio —actual papel de los

Por PEDRO A. EUROPEIZACIÓN DEL DERECHO PRIVADO. Re- laciones entre el Derecho privado y el ordenamiento comunitario. Ca- racterización del Derecho privado comunitario. A) Mecanismos

Volviendo a la jurisprudencia del Tribunal de Justicia, conviene recor- dar que, con el tiempo, este órgano se vio en la necesidad de determinar si los actos de los Estados

95 Los derechos de la personalidad siempre han estado en la mesa de debate, por la naturaleza de éstos. A este respecto se dice que “el hecho de ser catalogados como bienes de

1. LAS GARANTÍAS CONSTITUCIONALES.—2. C) La reforma constitucional de 1994. D) Las tres etapas del amparo argentino. F) Las vías previas al amparo. H) La acción es judicial en