SuperPascal es un lenguaje de programación imperativo y concurrente desarrollado por Per Brinch Hansen . [1] Fue diseñado como un lenguaje de publicación : una herramienta de pensamiento para permitir la expresión clara y concisa de conceptos en programación paralela. Esto contrasta con los lenguajes de implementación que a menudo son complicados con detalles de máquina y convenciones históricas. Fue creado para abordar la necesidad en ese momento de un lenguaje de publicación paralela. Podría decirse que pocos lenguajes hoy en día son lo suficientemente expresivos y concisos como para ser utilizados como herramientas de pensamiento.
Historia y desarrollo
SuperPascal se basa en el lenguaje secuencial Pascal de Niklaus Wirth , ampliándolo con características para una concurrencia segura y eficiente. Pascal en sí mismo se usó mucho como lenguaje de publicación en la década de 1970. Se utilizó para enseñar prácticas de programación estructurada y apareció en libros de texto, por ejemplo, sobre compiladores [2] y lenguajes de programación. [3] Hansen había desarrollado anteriormente el lenguaje Concurrent Pascal , [4] uno de los primeros lenguajes concurrentes para el diseño de sistemas operativos y sistemas de control en tiempo real .
Los requisitos de SuperPascal se basaron en la experiencia adquirida por Hansen durante tres años en el desarrollo de un conjunto de programas paralelos modelo, que implementaban métodos para problemas comunes en la informática . [5] Esta experimentación le permitió sacar las siguientes conclusiones sobre el futuro de la computación paralela científica :
- Los futuros ordenadores paralelos serán de propósito general , lo que permitirá a los programadores pensar en términos de configuraciones de procesos orientados a problemas . Esto se basó en su experiencia en la programación de redes de transputers , que eran procesadores de propósito general capaces de conectarse en matrices , árboles o hipercubos .
- Los problemas habituales en la ciencia computacional requieren únicamente paralelismo determinista , es decir, esperar la comunicación desde un canal particular , en lugar de desde varios.
- Los algoritmos científicos paralelos se pueden desarrollar en un lenguaje de publicación elegante y probar en una computadora secuencial . Cuando se establece que un algoritmo funciona, se puede implementar fácilmente en un lenguaje de implementación paralela.
Esto dio lugar a los siguientes requisitos para un lenguaje de publicación paralelo:
- El lenguaje debe extender un lenguaje estándar ampliamente utilizado con paralelismo determinista y comunicación de mensajes . Las extensiones deben estar en el espíritu del lenguaje estándar.
- El lenguaje debe permitir programar configuraciones arbitrarias de procesos paralelos conectados por canales de comunicación. Estas configuraciones pueden definirse de forma iterativa o recursiva y crearse de forma dinámica.
- El lenguaje debería permitir que un compilador de una sola pasada verifique que los procesos paralelos no interfieran de manera dependiente del tiempo.
Características
Las ideas clave en el diseño de SuperPascal fueron proporcionar una programación segura , con conceptos abstractos para el paralelismo. [6] [7]
Seguridad
SuperPascal es seguro en el sentido de que debería permitir que su compilador y sistema de ejecución detecten tantos casos como sea posible en los que los conceptos del lenguaje fallan y producen resultados sin sentido. [8] SuperPascal impone restricciones en el uso de variables que permiten que un compilador de una sola pasada verifique que los procesos paralelos sean disjuntos, incluso si los procesos usan procedimientos con variables globales, eliminando así los errores dependientes del tiempo. Varias características de Pascal eran ambiguas o inseguras y se omitieron en SuperPascal, como las etiquetas y gotolas declaraciones, los punteros y las declaraciones adelantadas. [6]
Paralelismo
Las características paralelas de SuperPascal son un subconjunto de occam 2, con la generalidad agregada de matrices de procesos dinámicos y procesos paralelos recursivos. [7]
Una parallelsentencia indica que la cantidad fija de sentencias que contiene debe ejecutarse en paralelo. Por ejemplo:
paralelo
fuente() |
hundir()
fin
Una foralldeclaración denota la ejecución paralela de una declaración por un número dinámico de procesos, por ejemplo:
para todo i := 0 a 10 hacer
algo()
Canales y comunicación
Los procesos paralelos se comunican enviando mensajes tipificados a través de canales creados dinámicamente. Los canales no son variables en sí mismos, sino que se identifican mediante un valor único conocido como referencia de canal , que se almacena en las variables de canal . Un canal se declara, por ejemplo, mediante la declaración
tipo canal = * ( booleano , entero ) ; var c : canal ;
que define un nuevo tipo (mixto) llamado canal y una variable de este tipo llamada c . Un canal de tipo mixto está restringido a transmitir únicamente los tipos especificados, en este caso valores booleanos y enteros. El canal c se inicializa con la opendeclaración:
abierto(c)
La comunicación de mensajes se logra entonces con las instrucciones send(channel, value)y receive(channel, variable). La expresión o variable que proporciona el valor para sendy la variable en receivedeben ser ambas del mismo tipo que el primer argumento del canal. El siguiente ejemplo muestra el uso de estas funciones en un proceso que recibe un valor del canal izquierdo y lo emite en el derecho .
var izquierda , derecha : canal ; a : número ; recibir ( izquierda , a ) ; enviar ( derecha , a )
Las funciones sendy receivepueden tomar múltiples argumentos de entrada y salida respectivamente:
enviar(canal, e1, e2,..., en); recibir(canal, v1, v2,..., vn)
Pueden ocurrir los siguientes errores de comunicación en tiempo de ejecución :
- La contención de canal ocurre cuando dos procesos paralelos intentan enviar o recibir en el mismo canal simultáneamente.
- Un error de tipo de mensaje ocurre cuando dos procesos paralelos intentan comunicarse a través del mismo canal y la expresión de salida y la variable de entrada son de tipos diferentes.
- Un bloqueo se produce cuando una operación de envío o recepción espera indefinidamente a que se complete.
Recursión paralela
Los procedimientos recursivos se pueden combinar con las instrucciones parallely forallpara crear procesos recursivos paralelos. El siguiente ejemplo muestra cómo se puede definir de forma recursiva una secuenciaparallel de procesos mediante una instrucción.
procedimiento pipeline ( min , max : entero ; izquierda , derecha : canal ) ; var middle : canal ; begin si min < max entonces begin open ( midge ) ; paralelo nodo ( min , izquierda , medio ) | pipeline ( min + 1 , max , medio , derecha ) end end else nodo ( min , izquierda , derecha ) end ;
Otro ejemplo es la definición recursiva de un árbol de procesos :
procedimiento árbol ( profundidad : entero , fondo : canal ) ; var izquierda , derecha : canal ; comienzo si profundidad > 0 entonces comienzo abierto ( izquierda , derecha ) ; paralelo árbol ( profundidad - 1 , izquierda ) | árbol ( profundidad - 1 , derecha ) | raíz ( fondo , izquierda , derecha ) fin fin de lo contrario hoja ( fondo )
Control de interferencias
El aspecto más difícil de la programación concurrente es el comportamiento impredecible o no reproducible causado por errores dependientes del tiempo . Los errores dependientes del tiempo son causados por interferencias entre procesos paralelos, debido a actualizaciones de variables o conflictos de canal. Si los procesos que comparten una variable la actualizan en momentos impredecibles, el comportamiento resultante del programa depende del tiempo. De manera similar, si dos procesos intentan enviar o recibir simultáneamente en un canal compartido, el efecto resultante depende del tiempo.
SuperPascal aplica ciertas restricciones en el uso de variables y comunicación para minimizar o eliminar errores dependientes del tiempo. Con las variables, se requiere una regla simple: los procesos paralelos solo pueden actualizar conjuntos disjuntos de variables. [1] Por ejemplo, en una paralleldeclaración, una variable de destino no puede ser actualizada por más de un solo proceso, pero una variable de expresión (que no puede ser actualizada) puede ser utilizada por múltiples procesos. En algunas circunstancias, cuando una variable como una matriz es el destino de múltiples procesos paralelos y el programador sabe que su uso por elemento es disjoint , entonces la restricción de disjunción puede ser anulada con una [sic]declaración precedente.
Estructura y sintaxis
SuperPascal es un lenguaje estructurado en bloques , con la misma sintaxis básica que Pascal. Un programa consta de un encabezado , definiciones de variables globales , definiciones de funciones o procedimientos y un procedimiento principal . Las funciones y los procedimientos constan de bloques , donde un bloque es un conjunto de sentencias . Las sentencias se separan con punto y coma, a diferencia de lenguajes como C o Java , donde se terminan con punto y coma.
El siguiente es un ejemplo de un programa SuperPascal completo, que construye una estructura de comunicación por canalización con 100 nodos. Un nodo maestro envía un token entero al primer nodo, que luego se transmite a lo largo de la canalización y se incrementa en cada paso, y finalmente lo recibe el nodo maestro y lo imprime.
canalización del programa ;
constante
len = 100 ;
tipo
canal = * ( entero ) ;
var
izquierda , derecha : canal ; valor : entero ;
procedimiento nodo ( i : entero ; izquierda , derecha : canal ) ; var valor : entero ; comienzo recibir ( izquierda , valor ) ; enviar ( derecha , valor + 1 ) fin ;
procedimiento crear ( izquierda , derecha : canal ) ; tipo fila = matriz [ 0 .. len ] de canal ; var c : fila ; i : entero ; comienzo c [ 0 ] := izquierda ; c [ len ] := derecha ; para i := 1 a len - 1 hacer abrir ( c [ i ]) ; para todo i := 1 a len hacer nodo ( i , c [ i - 1 ] , c [ i ]) fin ;
empezar
abierto ( izquierda , derecha ) ;
enviar paralelo ( izquierda , 0 ) | crear ( izquierda , derecha ) | recibir ( derecha , valor ) fin ;
writeln ( 'El valor resultante es ' , valor ) fin .
Implementación
Se puede acceder libremente al software SuperPascal desde el Archivo Brinch Hansen. [9] Consiste en un compilador y un intérprete, ambos escritos en Pascal secuencial normal (Pascal estándar ISO Nivel 1). Esto es compatible con el compilador GNU Pascal y versiones más nuevas del compilador Free Pascal (2.7.1+) con el -Misoconmutador, con las siguientes pequeñas modificaciones respectivas al código.
Para GPC, el archivo interpret.putiliza la función no estándar clock(línea 1786), que se utiliza para obtener la hora del sistema. En su lugar, getTimeStampse puede utilizar la función Extended Pascal (que es compatible con el compilador GNU Pascal), declarando una variable de tipo TimeStamp, estableciéndola con la hora actual mediante getTimeStampy asignando el Secondcampo de TimeStampa la variable t.
Free Pascal también necesita una solución al problema del "reloj" mencionado anteriormente (en Windows, simplemente declare gettickcount como externo con "clock" como nombre). Además, los reinicios/reescrituras que están marcados como no estándar en el código fuente deben cambiarse a pares de asignación/reinicio (o reescritura). (GPC probablemente solo genere errores en esto si habilita indicadores estrictos), y los comandos del preprocesador C #include 'xx' deben cambiarse a {$include 'xx'}.
{ Código de tiempo para readtime en Freepascal en sistemas Unix }
Función FpTime ( var tloc : entero ) : entero ; nombre externo 'FPC_SYSC_TIME' ;
procedimiento readtime ( var t : entero ) ; begin { Una función no estándar lee el tiempo del procesador en ms} t := fptime ( t ) ; end ;
Referencias
- ^ ab Hansen, Per Brinch (1993), SuperPascal: un lenguaje de publicación para computación científica paralela
- ^ Welsh, Jim (1980). Programación de sistemas estructurados . Upper Saddle River, NJ, EE. UU.: Prentice-Hall. ISBN 0-13-854562-6.
- ^ Tennent, RD (1981). Principios de lenguajes de programación . Upper Saddle River, NJ, EE. UU.: Prentice-Hall. ISBN 0-13-709873-1.
- ^ Hansen, Brinch (1977). La arquitectura de programas concurrentes . Prentice-Hall. ISBN 978-0130446282.
- ^ Hansen, Brinch (mayo de 1993), "Programas modelo para la ciencia computacional: una metodología de programación para multicomputadoras", Concurrency: Practice and Experience , pp. 407– 423
- ^ ab Hansen, Brinch (1994). "El lenguaje de programación SuperPascal". Software: Práctica y experiencia . 24, 5 : 399– 406.
- ^ ab Hansen, Brinch (1977). La invención de la programación concurrente . Nueva York: Springer-Verlag. ISBN 0-387-95401-5.
- ^ Hoare, CAR (1974). "Consejos sobre el diseño de lenguajes de programación". Computer System Reliability : 505– 534.
- ^ Hayden, CC (11 de junio de 2008). «Archivo Per Brinch Hansen» . Consultado el 3 de marzo de 2020 .
Enlaces externos
- Sitio web oficial , Archivo Brinch Hansen, un conjunto de sus artículos y el software SuperPascal que se puede descargar en un archivo comprimido; contiene la especificación completa del lenguaje y documentación útil.
- superpascal en GitHub , versión modificada de Christopher Long de la implementación original de SuperPascal; se compila y se ejecuta bajo Free Pascal moderno; la ejecución del programa es más rápida que Perl 5 o 6, casi tan rápida como Python 3
