Teoría, febrero 14-15

Anuncio
Programación Concurrente y de Tiempo Real
Grado en Ingenierı́a Informática
Examen Final Teórico de la Asignatura
Enero de 2015
1.
Apellidos:
Nombre:
D.N.I.:
Grupo (A ó B):
Notas
1. Escriba su nombre, apellidos, D.N.I. y grupo en el espacio habilitado para ello, y
en todos los folios blancos que utilice. Firme el documento en la esquina superior
derecha de la primera página.
2. Dispone de diez minutos para leer los enunciados y formular preguntas o aclaraciones sobre ellos. Transcurrido ese tiempo, no se contestarán preguntas. Dispone
de 90 minutos para completar el ejercicio.
3. No complete el documento a lápiz. Utilice bolı́grafo o rotulador. Escriba con
letra clara y legible. No podemos corregir lo que no se no puede leer.
4. Utilice los folios blancos que se le proporcionan para resolver los enunciados,
pero traslade a este documento únicamente la solución final que obtenga, utilizando el espacio especı́ficamente habilitado para ello, sin sobrepasarlo en ningún
caso, y sin proporcionar información o respuestas no pedidas. Entregue tanto el
enunciado como los folios blancos. Únicamente se corregirá este documento.
2.
Criterios de Corrección
1. El examen se calificará de cero a diez puntos, y ponderará en la calificación final
al 40 % bajo los supuestos recogidos en la ficha de la asignatura.
2. Cada enunciado incluye información de la puntuación que su resolución correcta
representa, incluida entre corchetes.
3. Un enunciado (cuestión teórica o problema) se considera correcto si la solución
dada es correcta completamente. En cualquier otro caso se considera incorrecto
y no puntúa.
1
4. Un enunciado de múltiples apartados (cuestión teórica o problema) es correcto
si y solo si todos los apartados que lo forman se contestan correctamente. En
cualquier otro caso se considera incorrecto y no puntúa.
3.
Cuestiones de Desarrollo Corto
Conteste a las preguntas que se le formulan en el espacio habilitado para
ello. Deberá razonar o justificar su respuesta siempre que se le indique. La ausencia del razonamiento o de la justificación invalidarán la respuesta al no ser
esta completa.
1. Considere una arquitectura Java-RMI que utiliza callback de cliente; ¿Serı́a
necesaria la activación del DNS rmiregistry en el lado del cliente para hacerla
completamente operativa? ¿Por qué? [0.5 puntos]:
2. Escriba una comparativa en formato tabular entre las especificaciones de
Java estándar y Java de tiempo real: [0.5 puntos]
2
3. Considere el siguiente programa en Java que hace uso de cerrojos synchronized.
¿Qué caracterı́stica de este tipo de cerrojos evita que el código se bloquee? ¿En
qué consiste esa caracterı́stica? [1 punto]
import java.util.Scanner;
public class cumbresTenebrosas extends Thread{
public static int v = 0;
public static int n = 1000;
public cumbresTenebrosas(){this.start();}
public void Heatcliff(){
if(n>0){
n--;
synchronized(this){v--;}
this.Heatcliff();
}
}
public void run(){
this.Heatcliff();
}
public static void main(String[]args){
cumbresTenebrosas q = new cumbresTenebrosas();
try{q.join();}catch(InterruptedException e){}
System.out.println(v);
}
}
Escriba aquı́ sus respuestas, justificándolas en ambos casos:
3
4. Considerando monitores teóricos tipo Hoare, ¿Qué diferencias hay entre
las semánticas de señalización SC y SX? ¿Qué elección a nivel de estructuras de
control de flujo debe tomar el programador según una u otra?
Escriba a continuación su respuesta razonada: [0.5 puntos]
5. Considere el siguiente programa que utiliza C-CUDA sobre una GPU
nVidia: [1.5 puntos]
__global__ void vecAdd(double *a, double *b, double *c, int n){
int id = blockIdx.x*blockDim.x+threadIdx.x;
if (id < n)
c[id] = a[id] * b[id];}
int main( int argc, char* argv[] ){
int n = 100000;
double *h_a; double *h_b; double *h_c;
double *d_a; double *d_b; double *d_c;
size_t bytes = n*sizeof(double);
h_a = (double*)malloc(bytes);
h_b = (double*)malloc(bytes);
h_c = (double*)malloc(bytes);
cudaMalloc(&d_a, bytes);
cudaMalloc(&d_b, bytes);
cudaMalloc(&d_c, bytes);
int i;
for( i = 0; i < n; i++ ) {
h_a[i] = sin(i)*sin(i);
h_b[i] = cos(i)*cos(i);
}
cudaMemcpy( d_a, h_a, bytes, cudaMemcpyHostToDevice);
cudaMemcpy( d_b, h_b, bytes, cudaMemcpyHostToDevice);
int blockSize, gridSize;
blockSize = 1024;
gridSize = (int)ceil((float)n/blockSize);
vecAdd<<<gridSize, blockSize>>>(d_a, d_b, d_c, n);
cudaMemcpy( h_c, d_c, bytes, cudaMemcpyDeviceToHost );
double sum = 0;
for(i=0; i<n; i++)
4
sum += h_c[i];
printf("final result: %f\n", sum/n);
cudaFree(d_a);
cudaFree(d_b);
free(h_a);
free(h_b);
free(h_c);
}
Conteste a las siguientes preguntas, justificando siempre su respuesta:
a) Indique qué segmento de código define el kernel, y qué se hace en él paralelamente en los cores de la GPU.
b) Indique con qué segmento de código se transfieren los datos a la GPU y
qué datos concretos se transmiten.
c) Indique qué segmento de código lanza la ejecución del kernel sobre los datos
en los núcleos CUDA.
5
6. Considere el siguiente programa escrito en Clojure. Indique la salida -si la hayque produce y el comportamiento que tiene. Justifique su respuesta. [1 punto]
(defn inc [valor n]
(dosync
(let [vactual @valor]
(alter valor + n))))
(defn dec [valor n]
(dosync
(let [vactual @valor]
(alter valor - n))))
(def vinic (ref 0))
(future
(future
(future
(future
(inc
(dec
(dec
(dec
vinic
vinic
vinic
vinic
2000000))
1000000))
1000000))
10))
(. Thread sleep 1000)
(println "Valor final: " @vinic)
Indique aquı́ la salida y el comportamiento, justificando ambos:
7. Se ha determinado que el coeficiente de bloqueo óptimo para una aplicación
paralela es de 0,85. Consteste, razonando su respuesta, las sigiente cuestiones:
[1 punto]
¿Qué significado tiene ese coeficiente de bloqueo?
6
En una máquina de 16 cores, ¿cuántas hebras en ejecución concurrente
habrá, a partir del coeficiente de bloqueo indicado?
Dibuje una curva con el comportamiento teórico esperado en tiempo de
respuesta de la aplicación, como una función del coeficiente de bloqueo,
sabiendo que para el valor óptimo de 0,85, la aplicación tardó 10 milisegundos.
Realice una interpretación de la curva de forma justificada:
8. Considere el siguiente programa escrito en C++11. Indique la salida -si la
hay- que produce y el comportamiento que tiene. Justifique su respuesta. [1
punto]
7
#include<iostream>
#include <thread>
int x = 0;
int nVueltas = 1000000;
void hola(){
std::cout <<"Hola Mundo...";
for(int i=0; i<nVueltas; i++)x++;
}
void adios(){
std::cout <<"Spock dice: larga vida y prosperidad...";
for(int i=0; i<nVueltas; i++)int x=2*x;
}
int main(){
std::thread h(hola);
std::thread i(hola);
std::thread j(adios);
h.join();
i.join();
j.join();
std::cout << x;
}
Indique aquı́ la salida y el comportamiento del programa anterior, justificando
ambos:
4.
Problemas
1. Considere el conjunto formado por las instrucciones siguientes:
a:=x+y;
b:=z-1;
8
c:=a-b
w:=c+1;
Escriba los conjuntos de lectura y escritura de todas ellas, y utilı́celos para
determinar cuáles se pueden ejecutar concurrentemente entre sı́. Proporcione
las relaciones entres instrucciones en formato tabular:[1 punto]
9
2. El API de concurrencia estándar de Java no dispone semáforos binarios.
Escriba una clase llamada semaf que los proporcione utilizando las primitivas
de control de la concurrencia que dicho API estándar proporciona.Escriba ahora,
utilizando herencia por extensión de la clase anterior, el código de una clase que
proporcione semáforos de conteo general. Llámela gsemaf. [2 puntos]
10
Descargar