Sunteți pe pagina 1din 42

LENGUAJE DE

PROGRAMACIÓN PARALELA
X10
Clase 1:
Introducción
Introducción
• X10 es un lenguaje de programación desarrollado por IBM.
• X10 está diseñado específicamente para la computación paralela
utilizando el modelo de Espacio de Direcciones Globales
Particionadas (PGAS).
• En este modelo, varios procesos paralelos ejecutan conjuntamente
un algoritmo al comunicarse entre sí a través de una memoria que
se comparte conceptualmente entre todos los procesos, es decir,
hay un solo espacio de direcciones.
• Sin embargo, a nivel de hardware, esta memoria compartida
conceptualmente, se realiza mediante varias memorias que están
interconectadas de manera que no todas las direcciones de
memoria lógica tienen la misma latencia de acceso.
• Estas memorias pueden pertenecer a uno o varios procesadores.
• Antes de PGAS, los modelos de programación paralelos podían agruparse en
dos grupos principales: modelos de paso de mensajes como MPI, donde los
procesos aislados con memorias aisladas intercambiaban mensajes (figura a)
• Y modelos de memoria compartida, como OpenMP, donde múltiples hilos
puede leer y escribir una memoria compartida (figura b).
• El modelo PGAS se puede ubicar entre estos modelos (figura c).

• En estos tres modelos, los procesos se representan como círculos y las


ubicaciones de memoria como rectángulos. Las líneas discontinuas muestran
accesos a la memoria, que en el caso del paso de mensajes pasan
explícitamente por un proceso distinto en forma de mensaje.
• Las líneas verticales entre los procesos y las secciones de memoria,
respectivamente sólidas, punteadas y ausentes, ilustran la distancia conceptual
entre las secciones de memoria y el costo asociado de acceder a sus datos.
X10
• X10 es un lenguaje de programación orientado a objetos.
• Un programa X10 comienza con un solo hilo de control. Tal hilo de
control se llama actividad1 (activity) y se ejecuta en un lugar2 (place) fijo,
es decir, no puede migrar entre lugares. Para iniciar el cálculo en otros
lugares, una actividad puede generar asincrónicamente otras actividades
en lugares remotos o locales con la sentencia async. Para sincronizar al
finalizar, se puede usar la sentencia finish.

1 Una actividad es una serie de sentencias que se ejecutan


independientemente con sus propias variables locales.
2Las particiones del espacio global de direcciones se denominan lugares.

Aunque los lugares en un programa X10 no necesariamente se asigna a


procesadores físicos o núcleos de procesamiento, la cantidad de lugares es
fijo y conocido al inicio del programa.
Concurrencia
• Programa concurrente: Es aquél que define acciones que pueden
realizarse simultáneamente. Puede ser una máquina con un
procesador.
• Programa paralelo: Es un programa concurrente diseñado para su
ejecución en un hardware paralelo. Puede ser una máquina con 2
o más procesadores que comparten memoria.
• Programa distribuido: Es un programa paralelo diseñado para su
ejecución en una red de procesadores autónomos que no
comparten memoria. Puede ser un conjunto de máquinas con uno
o más procesadores.
Algoritmos Seriales
• Un algoritmo serial es aquel en el que las tareas se ejecutan
una tras otra, debido a su dependencia de datos.
Algoritmos Paralelos
• Los algoritmos paralelos son aquellos en los cuales las tareas se
pueden ejecutar en paralelo al mismo tiempo, debido a su
independencia de datos.
Algoritmos Seriales Paralelos
• Un algoritmo serial paralelo es aquel en el que las tareas están
agrupadas en fases y se ejecutan en paralelo, además las fases
se ejecutan de manera secuencial.
Sincronización
• En un programa concurrente existe una necesidad de
sincronización entre los procesos.
• Una forma de sincronizar es utilizando barreras.
• Una barrera es utilizada o definida cuando se necesitan
sincronizar diferentes tareas independientes que deben de
completarse antes de ejecutar el resto.
Ejecutando el X10
Presentación
Creando el proyecto
1er programa: Hola Mundo
El programa
Activando los procesadores
Activando los procesadores
Activando los procesadores
Argumentos iniciales
Argumentos iniciales
Creando una clase
Creando una clase
Creando una clase
Tipo de datos
Tipo de datos
Estructuras de control
• Ejemplo if else:

val i:Long=3;
if(i==3){
Console.OUT.println("Es igual a tres");
}
else{
Console.OUT.println("No es igual a tres");
}
Estructuras de control
• Ejemplo switch:

val i:Int=3n;
switch(i){
case 1n: Console.OUT.println("uno");
break;
case 2n: Console.OUT.println ("dos");
break;
case 3n: Console.OUT.println("tres");
Console.OUT.println("La suma es "+(i+7));
break;
default: Console.OUT.println("Otro valor");
break;
}
Estructuras de control
• Ejemplo while:

var n:Long=5;
while(n>1){
n=n-1;
Console.OUT.println(n);
}
Estructuras de control
• Ejemplo do-while:

var n:Long;
n=5;
do {
n=n-1;
Console.OUT.println(n);
} while (n>1);
Estructuras de control
• Ejemplo for:

var n:Long;
for(n=1;n<5;n++)
{
Console.OUT.println(n);
}
Serie de Fibonacci: Secuencial
import x10.io.Console;
public class ejemplo {
public static def main(args:Rail[String]) {
val n = 20;
Console.OUT.println("Calculando hasta fib("+n+")");
var x:Long=0;
var y:Long=1;
var z:Long=0;
var i:Long;
Console.OUT.print(x+"-");
Console.OUT.print(y+"-");
for(i=1;i<n;i++)
{
z=x+y;
Console.OUT.print(z+"-");
x=y;
y=z;
}
}
}
Serie de Fibonacci: Recursivo
import x10.io.Console;
public class ejemplo {
public static def fib(n:long) {
if (n<=2) return 1;
val f1:long;
val f2:long;
f1 = fib(n-1);
f2 = fib(n-2); //llamada recursiva
return f1 + f2;
}
public static def main(args:Rail[String]) {
val n = 20;
Console.OUT.println("Calculando hasta fib("+n+")");
Console.OUT.print("0-");
for(var i:Long=1;i<=n;i++)
Console.OUT.print(fib(i)+"-");
}
}
Serie de Fibonacci: Paralelo
import x10.io.Console;
public class ejemplo {
public static def fib(n:long) {
if (n<=2) return 1;
val f1:long;
val f2:long;
finish{
async f1 = fib(n-1);
async f2 = fib(n-2); //llamada recursiva
}
return f1 + f2;
}
public static def main(args:Rail[String]) {
val n = 20;
Console.OUT.println("Calculando hasta fib("+n+")");
Console.OUT.print("0-");
for(var i:Long=1;i<=n;i++)
Console.OUT.print(fib(i)+"-");
}
}
Calculo de PI: Método Montecarlo
El método de Montecarlo consiste en dibujar dentro de un
cuadrado de lado 1, una circunferencia con radio 1, generar
coordenadas x, y aleatorias en el rango de 0 a 1 y calcular PI,
utilizando la siguiente fórmula.
Calculo de PI: Secuencial
import x10.io.Console;
import x10.util.Random;
public class ejemplo {
public static def main(args:Rail[String]){
val r= new Random( );
var resultado:Double=0;
var i:Long;
val N = 1e8;
Console.OUT.println("Calculando PI con "+N+ " iteracciones");
for(i=0;i<N;i++)
{
val x=r.nextDouble();
val y=r.nextDouble();
if(x*x + y*y <=1)resultado++;
}
val pi=4*resultado/N;
Console.OUT.println("PI: "+pi);
}
}
Calculo de PI: Paralelo (Incorrecto)
import x10.io.Console;
import x10.util.Random;
public class ejemplo {
public static def main(args:Rail[String]){
val r= new Random( );
var resultado:Double=0;
var i:Long;
val N = 1e6;
Console.OUT.println("Calculando PI con "+N+ " iteracciones");
finish async for(i=0;i<N;i++)
{
val x=r.nextDouble();
val y=r.nextDouble();
if(x*x + y*y <=1)resultado++;
} Esta paralización no es
val pi=4*resultado/N; eficiente puesto que envía
Console.OUT.println("PI: "+pi); a otro place todo el
} calculo de for mientras el
} resto del programa espera
a que termine.
Calculo de PI: Paralelo (Correcto)
import x10.io.Console;
import x10.util.Random;
public class ejemplo {
public static def main(args:Rail[String]){
val r= new Random( );
var resultado:Double=0;
var i:Long;
val N = 1e6;
Console.OUT.println("Calculando PI con "+N + " iteracciones");
for(i=0;i<N;i++)
{
val x:double;
val y:double;
finish{
async x=r.nextDouble();
async y=r.nextDouble();
}
Esta paralización si es
if(x*x + y*y <=1)resultado++;
} eficiente puesto que envía
val pi=4*resultado/N; el calculo de las variables
Console.OUT.println("PI: "+pi); x e y a lugares diferentes
} realizándose así un calculo
}
paralelo.
Calculo de PI: Suma de Riemann
Es la aproximación de la siguiente integral de 0 a 1.

dx
Calculo de PI: Secuencial
import x10.io.Console;
public class ejemplo {
public static def main(args:Rail[String]) {
val total=1e8;
var paso:Double; El resultado es:
var x:Double; PI es: 3.1415926535904264
var pi:Double;
var sum:Double=0.0; Este código no se puede
var i:Long; paralelizar tal como está.
paso=1.0/total; Escriba nuevamente el código,
for(i=0;i<total;i++) dividiendo el for en cuatro for,
{
paralelizándolos.
x=(i+.5)*paso;
sum=sum+4.0/(1.0+x*x);
}
pi=sum*paso;
Console.OUT.println("PI es: " + pi);
}
}
Calculo de PI: Paralelo
import x10.io.Console; async for(i3=2*total as long/4;i3<3*total/4;i3++)
public class ejemplo { {
public static def main(args:Rail[String]) { x3=(i3+.5)*paso;
val total=1e8; sum3=sum3+4.0/(1.0+x3*x3);
var paso:Double; }
var x1:Double,x2:Double,x3:Double,x4:Double; async for(i4=3*total as long/4;i4<total;i4++)
var pi:Double; {
var sum:Double=0.0,sum1:Double=0.0,sum2:Double=0.0; x4=(i4+.5)*paso;
var sum3:Double=0.0,sum4:Double=0.0; sum4=sum4+4.0/(1.0+x4*x4);
var i1:Long,i2:Long,i3:Long,i4:Long; }
paso=1.0/total; }
finish{ sum=sum1+sum2+sum3+sum4;
async for(i1=0;i1<total/4;i1++) pi=sum*paso;
{ Console.OUT.println("PI es: " + pi);
x1=(i1+.5)*paso; }
sum1=sum1+4.0/(1.0+x1*x1); }
}
async for(i2=total as Long/4;i2<2*total/4;i2++)
{
x2=(i2+.5)*paso;
El resultado es:
sum2=sum2+4.0/(1.0+x2*x2); PI es: 3.1415926535896825
}
Timer
import x10.io.Console;
import x10.util.Timer;
public class Hola {
public static def main(args:Rail[String]){
val tiempo=new Timer();
val ini:Long;
val fin:Long;
ini=tiempo.nanoTime();
for(var i:Long=1;i<=1e6;i++){
}
fin=tiempo.nanoTime();
//Tambien puede usar milliTime()
Console.OUT.println("Inicio: "+fin+"\nFin: "+ini);
Console.OUT.println("Tiempo transcurrido en ns: "+(fin-ini));
}
}
Ejercicio
Realice cuatro sumas parciales de 1 hasta 1e10 y luego sume el
total.
a) Secuencialmente
b) Paralelamente
¿Encuentra diferencia en los tiempos empleados?
Fin de Clase 01

S-ar putea să vă placă și