Documente Academic
Documente Profesional
Documente Cultură
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).
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