stringtranslate.com

Ateji PX

Ateji PX es una extensión del lenguaje de programación orientado a objetos para Java . Su objetivo es facilitar la computación paralela en procesadores multinúcleo , GPU , Grid y Cloud.

Ateji PX se puede integrar con el IDE Eclipse , requiere un aprendizaje mínimo de las construcciones paralelas adicionales y no altera el proceso de desarrollo.

Ejemplos de código

Hola Mundo

clase pública HolaMundo { public static void main ( String [] args ) { [ || System . println ( " Hola" ) ; || System . println ( " Mundo " ); ] } }                

Cada ||símbolo introduce una rama paralela. Al ejecutar este programa se imprimirá

HolaMundo

o

MundoHola

dependiendo de cómo se programen las ramas paralelas.

Paralelismo de datos

[ || ( int i : matriz . longitud ) matriz [ i ]++ ; ]      

La cuantificación (int i : N)crea una rama paralela para cada valor de i. El efecto de este código es incrementar todos los elementos de arrayen paralelo. Este código es equivalente a

[ || matriz [ 0 ]++ ; || matriz [ 1 ]++ ; ... || matriz [ matriz . longitud - 1 ]++ ; ]       

Se pueden realizar cuantificaciones más complejas. El siguiente ejemplo cuantifica sobre el triángulo superior izquierdo de una matriz cuadrada:

[ || ( int i : N , int j : N , si i + j < N ) matriz [ i ][ j ]++ ; ]       

El código que realiza una operación similar y generalmente pequeña en una gran colección de elementos se denomina data parallel y aparece a menudo en aplicaciones científicas de alto rendimiento. Un representante típico de los lenguajes data-parallel para los ecosistemas C/C++ o Fortran es OpenMP .

Las funciones de paralelismo de datos también pueden implementarse mediante bibliotecas que utilicen estructuras de datos dedicadas, como matrices paralelas .

Paralelismo de tareas

El término paralelismo de tareas se utiliza cuando el trabajo se puede descomponer conceptualmente en varias tareas lógicas. En este ejemplo, las tareas se crean de forma recursiva:

int fib ( int n ) { if ( n <= 1 ) return 1 ; int fib1 , fib2 ; // crea ramas paralelas recursivamente [ || fib1 = fib ( n - 1 ); || fib2 = fib ( n - 2 ); ] return fib1 + fib2 ; }                           

El paralelismo de tareas se implementa en lenguajes como Cilk y en bibliotecas similares al fork/joinpar de llamadas al sistema Unix.

Paso de mensajes

Las ramas paralelas tienen dos formas de comunicarse: leyendo y escribiendo simultáneamente variables compartidas o enviando mensajes explícitos. Los operadores !y ?envían y reciben respectivamente un mensaje en un canal.

En este ejemplo, dos ramas paralelas se comunican mediante el paso de mensajes explícito:

Chan < String > chan = new Chan < String > (); [ // la rama 1 envía un valor a través del canal || chan ! "Hola" ;          // la rama 2 recibe un valor del canal y lo imprime || chan ? s ; System . out . println ( s ); ]     

Flujo de datos

Se dice que un programa es un flujo de datos cuando el cálculo se inicia y se sincroniza mediante la disponibilidad de datos en un flujo. Un ejemplo típico es un sumador: tiene dos entradas, una salida y, siempre que las dos entradas están listas, envía su suma a la salida.

void sumador ( Chan < Entero > in1 , Chan < Entero > in2 , Chan < Entero > out ) { para (;;) { int valor1 , valor2 ; [ in1 ? valor1 ; || in2 ? valor2 ; ] ; out ! valor1 + valor2 ; }}                           

Tenga en cuenta la lectura paralela [ in1 ? value1; || in2 ? value2; ]. Esto significa que los dos valores de entrada pueden venir en cualquier orden. Sin ella, el código puede bloquearse si los valores llegan en el orden incorrecto. Esto demuestra que las primitivas paralelas en un lenguaje de programación no solo tienen que ver con el rendimiento, sino también con el comportamiento de los programas.

El sumador por sí solo no hace nada, ya que reacciona a los datos de entrada. Debe colocarse en un contexto donde otras partes ingresen valores de entrada y lean valores de salida. La forma de expresar esto es componer todas las piezas en un gran bloque paralelo:

[ || source ( c1 ); // genera valores en c1 || source ( c2 ); // genera valores en c2 || adder ( c1 , c2 , c3 ); || sink ( c3 ); // lee valores de c3 ]             

Cualquier cosa que pueda considerarse una combinación de puertas lógicas o circuitos eléctricos puede expresarse fácilmente de esta manera como un programa de flujo de datos.

Enlaces externos