Examen Final PCA - 0910 -Q2 23 de Junio del 2010

Anuncio
Nombre y Apellidos:...................................................................................................................
Examen Final PCA - 0910 -Q2
23 de Junio del 2010
Las notas del examen y de la práctica se publicarán antes del 2 de Julio a las 23:59.
Para hacer la revisión tenéis que enviar un correo a [email protected] (examen) o a tu
profesor de laboratorio para la práctica antes del 4 de Julio a las 23:49.
Instrucciones:
Suponed que estáis trabajando con el ordenador del laboratorio.
1. (1 punto) Indicad qué herramientas y detalla cuáles son los pasos que realizarías para saber en
qué funciones se invierten o se producen o se ejecutan más: (1) Tiempo de CPU, (2) Fallos de cache
(primer o segundo nivel), (3) Instrucciones de multiplicar/dividir y (4) elapsed time.
2. (1 punto) ¿En qué consiste la técnica de blocking y para qué sirve?. Pon un ejemplo en el que tenga
sentido aplicar blocking.
3. (1.5 puntos) En el Core2 Duo que tenemos en los laboratorios, ¿qué tipo de ejecución de un programa
podemos realizar: concurrente, en paralelo o ninguna de ellas? Razona tu respuesta. En caso de
poderse ejecutar de forma concurrente y/o en paralelo, pon un ejemplo de código para cada tipo de
ejecución (concurrente o en paralelo) que podamos aprovechar.
4. (0.75 puntos) Escribid un código en C para cada caso y utilizando bit hacks, que implemente: (1)
el valor absoluto de una variable entera x de 32 bits , (2) el máximo de dos variables enteras x e y de
32 bits y (3) indique (resultado diferente de 0) si el valor, entre 1 y 32, de una variable entera x de 32
bits es primo.
5. (0.75 puntos) ¿Qué es más importante, la latencia de una instrucción o el "repetition rate"? Razona
tu respuesta con ejemplos.
6. (5 puntos) Dado el siguiente código:
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
typedef struct{
float f[16];
char un;
char dos;
float tres;
} tipo_t;
typedef struct
{
float f;
char siuuuuuu;
char boom[230610];
} tipo2_t ;
void procesar (tipo_t *A, tipo2_t *B, char *already_done, int print_debug, int N_ATOMS)
{
int i,x;
float tmp_calcul;
for (i=0; i<N_ATOMS; i++)
already_done[i]=0;
for (i=5; i<N_ATOMS; i++)
{
x = rand()%N_ATOMS;
tmp_calcul = 0.0;
if (!already_done[x] && (x < N_ATOMS-3))
{
already_done[x] = 1;
tmp_calcul = (A[x].f[0] * A[x+1].f[1] * A[x+2].f[2] * A[x+3].f[3]);
if (print_debug) printf("Value: %d tmp_calcul=%f\n", x, tmp_calcul);
}
B[i].f = B[i-4].f + tmp_calcul;
B[i].f += B[i-5].f + sqrtf((float)tmp_calcul);
}
for (i=N_ATOMS-1; i>=3; i--)
if (already_done[i]) B[i].f = B[i-1].f * B[i-3].f;
}
int main(int argc, char *argv[])
{
int N_ATOMS;
int print_debug;
tipo_t * A;
tipo2_t * B;
char * already_done;
N_ATOMS = atoi(argv[1]);
print_debug = atoi(argv[2]);
A = (tipo_t *) malloc(sizeof(tipo_t) * N_ATOMS);
B = (tipo2_t *) malloc(sizeof(tipo2_t) * N_ATOMS);
already_done = (char *) malloc(sizeof(char) * N_ATOMS);
/* Inicializaciones de fichero y calculos ...
*/
procesar(A,B,already_done,print_debug,N_ATOMS);
/* Mas procesos sobre A, B */
/* Imprime los resultados */
return 0;
}
(a) Optimizadlo (sin usar paralelización) escribiendo el código optimizado e indicando las técnicas de
optimización usadas. Sabemos que el profiling nos da esta información:
• La función procesar se lleva el 99% del tiempo de ejecución del programa.
• Se invierten muchos ciclos en las operaciones de coma flotante, sobretodo en las de multiplicar
y sqrtf.
• No se está explotando suficientemente la localidad de datos.
• La cantidad de saltos perjudica la localidad espacial de instrucciones del programa. En
cambio, la tasa de fallos de predicción de saltos no es muy elevada.
Descargar