Procesadores y microprocesadores Transputer
     

 

 

TRANSPUTERS

 

 

Un transputer es básicamente un dispositivo VLSI con un microprocesador RISC de 16 o 32 bits, según el modelo, con memoria y enlaces de comunicación para conectarse directamente a otros transputers.

 

1. FUNCIONAMIENTO DEL TRANSPUTER

 

La arquitectura de un transputer corresponde al siguiente esquema:

Arquitectura de un transputer.

 

El primer bloque a tener en cuenta es el correspondiente al procesador, como ya se ha señalado, es un sistema de 16 o 32 bits que incluye lógica de procesamiento de instrucciones, punteros de instrucción y de espacio de trabajo y un registro de operando. El bloque de memoria interna corresponde a RAM de alta velocidad de 4 Kbytes (2 Kbytes en las versiones más antiguas), externamente puede direccionar hasta 4 Gbytes de memoria (64 Kbytes en la versión 16 bits) a través del interfaz de memoria externa (EMI).

 

 

REGISTROS

El procesador contiene los registros A, B y C que son utilizados para la aritmética con enteros y para las direcciones, con estos tenemos una pila hardware, denominada pila de evaluación. Puede ir acompañado de un coprocesador aritmético en coma flotante de 64 bits (FPU), el cual tendría sus correspondientes registros AF, BF y CF. La razón de ser de esta pila es la forma en que los transputers realizan sus operaciones que sería siguiendo la notación polaca inversa. No existe ningún mecanismo hardware que indique que la pila haya cargado más de tres elementos, así que se supone que esta tarea se deja en manos del compilador.

Existen tres registros adicionales que son usados por el microprocesador con las finalidades de puntero al espacio de trabajo (workspace), apuntando a la zona donde son guardadas las variables locales; puntero de instrucción (next inst), que apuntaría a la siguiente instrucción que será ejecutada; y el registro de operando (operand).

 

Registros.

 

Estableciendo una analogía con el Intel 8086, next inst equivaldría al IP (instruction pointer) y operand coincide en algunos usos del SI. No existe ningún registro equivalente al stack pointer, de ahí el problema antes señalado de la imposibilidad de determinar que la pila de evaluación haya saturado.

 

INSTRUCCIONES

Los diseñadores de INMOS pretendieron realizar un conjunto de instrucciones simple, donde todas las instrucciones mantienen el mismo formato. Cada instrucción consta de un byte donde el nibble más significativo es el código de la función y el menos significativo es el dato o valor correspondiente.

 

Formato de instrucción.

 

Cuatro bits permiten representar hasta dieciséis comandos, a partir de las cuales podrán ser codificadas las funciones más importantes. Trece de estas funciones están destinadas para la carga y el almacenaje de valores, saltos y llamadas a subrutinas. Estas se denominan funciones directas.

Las dos funciones de prefijo permiten al operando de cualquier función ser extendido en longitud de forma que el contenido del nibble menos significativo de la instrucción, el dato, es desplazado al registro operand. Estas funciones tienen la ventaja de ser descodificadas y ejecutadas de la misma forma que las demás, simplificando y acelerando la descodificación de las instrucciones. Por otro lado la compilación se simplifica en cuanto permite a las instrucciones tomar operandos de cualquier tamaño, independizándolo del ancho de bits del bus del procesador.

El último de tipo de funciones que nos encontramos permite interpretar su operando como operación sobre el contenido en la pila de evaluación, permitiendo tener en una instrucción hasta dieciséis operaciones distintas, que incluirían operaciones aritméticas, lógicas y de comparación. A este tipo de funciones se le denomina funciones indirectas.

 

Tabla de funciones.

Tipo de función Función Mnemónico
Función directa add constant add
call call
conditional jump cj
jump j
load constant ldc
load local ldl
load local pointer ldlp
load non-local ldnl
store local stl
store non-local stnl
Función de prefijo prefix pfix
negative prefix nfix
Función indirecta operate opr

 

Parece ser que alrededor del setenta por ciento de las instrucciones ejecutadas son codificadas en un sólo byte, así las instrucciones de prefijo son poco usadas, necesitando sólo, la mayoría de las veces, un único ciclo de instrucción.

 

Tabla de operaciones.

Tipo de operación Operación Mnemónico
Lógica and and
or or
xor exclusive or
not bitwise not
Desplazamiento shl shift left
shr shift right
Aritmética y comparación gt greater than
diff difference
sum sum
prod product for register A
add add
sub substract
mul multiply
fmul fractional multiply
div divide
rem remainder
 

 

MEMORIA

 

MEMORIA INTERNA

Se distinguen dos bloques de memoria: el de memoria interna y el de memoria externa.

La memoria interna suele ser de 4 Kbytes permitiendo un rango de comunicación de hasta 120 Mbytes por segundo. Cada acceso a esta memoria implicaría un ciclo de procesador.

En los transputers la memoria se direcciona por bytes, tomando palabras de dos o cuatro bytes. El byte menos significativo de la palabra es el que tiene la dirección menor. Los bits de cada byte se numeran de cero a siete, donde el cero sería el menos significativo. Es decir sigue el convenio little-endians.

En la familia T800 la memoria interna comienza en la dirección #80000000 y llega hasta la dirección #80000FFF, comenzando la memoria de usuario en la #80000070, habiendo por tanto 112 bytes reservados. El uso principal de este espacio reservado es para los canales y enlaces, dos de esos doscientos doce byte se reservan para el uso del temporizador y el resto para movimiento de bloques y operaciones en punto flotante. A la dirección de comienzo de la memoria de usuario se la denomina MemStart.

 

MEMORIA EXTERNA

La memoria externa puede ser de hasta 4 Gbytes (60 Kbytes en los transputers de 16 bits), comenzado en la dirección #80001000. La conexión se realiza a través del interfaz de memoria externa, EMI, que se trata de un bus multiplexado del mismo modo que el 8086 pero con 32 bits para datos y direcciones (16 bits en los T222), siendo la velocidad de transmisión inferior a la de la memoria interna, llegando a los 60 Mbytes por segundo.

El espacio entre #00000000 y #7FFFFFFF está normalmente reservado para la ROM, siendo la dirección #7FFFFFFE (#7FFE para 16 bits) la de arranque. Para que dicho arranque sea posible desde ROM, habrá que poner a nivel alto la línea BFR, boot from ROM. En caso de estar dicha línea a cero, el transputer efectuaría la carga del programa a partir de un link; esta sería la otra forma de arrancarlo.

 

ACCESO DIRECTO A MEMORIA

El acceso directo a memoria o DMA aquí se produce como en cualquier otro microprocesador con la particularidad de permitir al procesador acceder a su memoria interna simultáneamente a la transferencia DMA, lo que no es posible hacer con la memoria externa. Ello implica que el dispositivo de DMA no tiene acceso a la memoria interna.

 

MOVIMIENTO DE BLOQUES DE PALABRAS

La idea está en mover bloques de memoria con el mínimo número de procesos de lectura y escritura. Cuando este proceso es interrumpido por otro de mayor prioridad se acabaría de escribir por completo la palabra en la que en ese momento se encontraba la transferencia y se detendría el movimiento de bytes. Al acabar el proceso que interrumpió continuaría la transferencia repitiendo la última palabra escrita.

 

 

SERVICIOS DEL SISTEMA

 

ENTRADA A RELOJ

Toda la familia de componentes relacionados con los transputers usan una frecuencia de reloj común, 5 MHz. La conexión entre los dispositivos es de naturaleza asíncrona, de forma que no nos importa en principio tener un reloj por componente conectado que tener uno solo que distribuya la señal a todo el sistema. El pin responsable de esto es ClockIn.

Conviene señalar que el ciclo interno del microprocesador va a ser mayor, desde 15 a 100 MHz, consiguiéndose gracias al empleo de un oscilador interno.

Cada transputer incluye dos temporizadores de 32 bits que funcionan a partir de la generación de pulsos periódicos. Uno de los temporizadores es sólo accesible para los procesos de alta prioridad y se incrementaría cada microsegundo, acabando un ciclo cada 4295 segundos. El otro es accesible por procesos de baja prioridad, incrementándose cada 64 microsegundos, siendo 15625 pulsos un segundo. Un periodo se completaría en 76 horas. El valor actual de los relojes puede ser leído ejecutando la instrucción load timer, usando la instrucción timer input podemos dejar un proceso dormido hasta que llegue determinado instante de tiempo.

 

RESET Y ARRANQUE

El reset activado forzaría la inicialización del transputer con el comienzo de la consiguiente rutina de arranque. Los links de salida se pondrán a cero, y los de entrada deben de estar también a cero.

A veces nos puede interesar mirar o incluso cambiar alguna localización en la memoria, el momento de hacer esto es cuando el transputer está esperando el arranque desde un enlace. Cuando ocurre esto, el transputer espera por el link un byte de control que indicará el número de bytes a ser leídos a través del enlace. Si el byte de control tuviera un 0 entonces el microprocesador esperaría ocho bytes más, de forma que los cuatro primeros contendrían la dirección de memoria sobre la que escribir el contenido de los cuatro bytes siguientes. Si el byte de control contuviera el valor 1, se esperarían cuatro bytes por el link que serían la dirección de la que nos interesa leer su contenido, que vendrían dados a través del canal de vuelta de dicho link. Esto se podría repetir hasta que se recibiera un byte de control cuyo valor fuera mayor que 1.

 

ERRORES

Hay cierto tipo de situaciones que pueden causar que los procesos no vayan bien. En esos casos la patilla ErrorOut se activará indicando la existencia de errores en algún proceso.

Una línea muy útil del procesador es Analyse que permite detener el funcionamiento del procesador, manteniendo los procesos de lectura y escritura en los links, hasta completar los buffers. En ese momento se puede usar la señal de reset para ver el contenido de las direcciones de memoria como ya ha sido explicado.

 

PROCESOS Y CONCURRENCIA

Un proceso es una secuencia de instrucciones. Considerándolo de esta manera un proceso se activará, comenzará a ejecutarse, efectuará una serie de tareas y finalmente se detendrá, o bien definitivamente, o bien por unos momentos quedando inactivo.

El microprocesador contiene el denominado microcoded scheduler o repartidor microcodificado, el cual permite a un cierto número de procesos concurrentes ser ejecutados juntos, compartiendo el tiempo de procesador. Esto evita la necesidad de un kernel por software que se encargue del reparto de procesos.

A cada proceso se le asignará alta o baja prioridad. Los procesos de baja prioridad se podrán ejecutar mientras no hayan procesos de alta prioridad. Los de alta prioridad deben de ser procesos de corta duración, en caso de haber varios de éstos esperando, se escogerá uno de ellos y correrá hasta que necesite esperar una comunicación, un valor del temporizador o bien finalice. Si sólo hay en espera procesos de baja prioridad, que se suponen de mayor duración, se repartirán secciones de tiempo entre estos.

El catálogo funciona de tal manera que cuando un proceso está inactivo no consume tiempo de procesador. Existen dos listas enlazadas donde los procesos esperan para ser ejecutados. Cada lista engloba los procesos de una prioridad.

 

 

 

 

 

 

 

 

 

 

 

Diagrama de estados de los procesos.

 

Cada lista se implementa con dos registros, el primero de los cuales apunta al primero de los procesos de la lista y el otro al último. Estos serían los registros Fptr y Bptr (pointer to front of active process list y pointer to back of active process list). A la lista de mayor prioridad se designa con un 0 y a la menor prioridad con un 1.

 

Lista enlazada para procesos de baja prioridad.

 

A los procesos de baja prioridad sólo les es posible funcionar durante dos cuantos de 5120 ciclos de reloj externo a 5 MHz (unos dos milisegundos en total). Si hubieran n procesos de baja prioridad el último proceso habría de esperar un máximo de 2n-2 cuantos (unos 4n-4 milisegundos).

Un proceso sólo puede ser dormido con ciertas instrucciones denominadas descheduling points. Si el proceso a ser despertado en la lista no pudiera ser llevado a cabo, su puntero de instrucción es guardado en su espacio de trabajo y se tomaría el siguiente proceso de la lista.

El procesador tiene una serie de operaciones especiales que permiten manejar los procesos tales como start process y end process. Cuando el proceso principal ejecuta un programa con procesos en paralelo, start process es la instrucción usada para crear los procesos concurrentes, de forma que se añade un nuevo espacio de trabajo al final de la lista enlazada correspondiente, creando un nuevo proceso.

La instrucción end process permite que los programas en paralelo terminen sin problemas. End process usa una parte del espacio de trabajo como contador de los procesos concurrentes que quedan aún por terminar. El contador se inicializa con el número total antes de que ningún proceso empiece a funcionar. Todos los procesos cuando terminan decrementan el contador y comprueban su valor. En último proceso avisaría al proceso principal.

 

EVENTOS

Los transputers no disponen de un sistema de interrupciones tal y como podrían disponer otros microprocesadores. En vez de esto se utilizan los eventos por línea, de tal forma que se puede desencadenar un único proceso dentro de un transputer por medio de la aparición de un evento en un instante dado. Cuando haya comenzado el proceso el transputer ofrece un nivel alto en su salida de reconocimiento de eventos, lo cual permite determinar la causa del evento y actuar sobre ella.

 

COPROCESADOR MATEMÁTICO

Los modelos más avanzados de transputers incorporan un coprocesador aritmético en coma flotante (FPU) de 64 bits, llegando a alcanzar velocidades de 4,3 Mflops. Al igual que el microprocesador principal tiene tres registros de pila, AF, BF y CF, siendo aquí de 64 bits.

Este dispositivo es accesible tanto para los procesos de alta como de baja prioridad. Cuando un proceso de alta prioridad interrumpe a otro de baja que está usando la FPU, la FPU guarda su estado y no le permite el acceso hasta que el proceso de baja prioridad haya acabado su operación actual, cosa que no haría la CPU.

A veces es necesario transmitir datos entre la CPU y la FPU, los puntos donde esto ocurre se denominan puntos de sincronización. Aquí el primero en estar listo para la transmisión esperará al otro. Cuando ambos están preparados actúan concurrentemente, de forma que la CPU se dedica a calcular las direcciones origen o destino de los datos en coma flotante y la FPU realizaría mientras operaciones sobre un cierto conjunto de datos. Esto se hace así con la idea de evitar tiempos muertos en ninguno de los dos.

 

MODELOS DE TRANSPUTERS

 

LA FAMILIA DE LOS TRANSPUTERS

La familia de los transputers es amplia, el primer microprocesador en salir al mercado fue el T414, lo hizo en septiembre de 1985; se trataba de un sistema de 32 bits, a 15 MHz a una escala de integración de 1,2 micras. Su memoria interna era de 2 Kbytes a una velocidad de transmisión de 80 Mbytes por segundo y con la memora externa de 26 Mbytes por segundo. Modelos posteriores llegaron a funcionar hasta a 20 MHz.

Más tarde salió la versión barata de 16 bits, el T212 sustituido más tarde por el T222 con 4 Kbytes de memoria interna.

Por otro lado aparecieron los T800, ya en 1987, similares a los T414 pero con 4 Kbytes de memoria interna con una velocidad de acceso de 120 Mbytes por segundo en los modelos más potentes, y 40 Mbytes por segundo con la externa, y coprocesador de coma flotante. Surgió la necesidad entonces de poder implementar depuración. Los modelos T805 y T801 completaron la familia de los transputers con coprocesador, donde el T801 había mejorado la velocidad de acceso a la memoria externa hasta 60 Mbytes por segundo.

El modelo T225 es una mejora del T222 que incluye soporte de depuración. Salió poco después que el T425.

Modelos posteriores fueron los T8000 y T9000 que, al parecer, fueron versiones mejoradas de la serie T800.

 

Tabla. Comparación de varios de los transputers que hay en el mercado.

 
T222
T225
T414
T425
T800
T801
T805
H1
Bits
16
16
32
32
32
32
32
32
MHz (máx.)
20
20
20
30
30
30
30
100
MIPS
20
30
20
30
30
30
30
150
FPU (Mflops)
no
no
no
no
4,3
4,3
4,3
4,3
RAM interna (Kbytes)
4
4
2
4
4
4
4
16

 

El último de transputer que salió fue el H1 en 1990, con una velocidad de 100 MHz, capaz de ejecutar ciento cincuenta millones de operaciones en punto flotante. Junto a este modelo se desarrolló un circuito integrado de apoyo, el C104, que mejoró de forma espectacular la interconexión entre estos modelos de transputers.

Pese a ello no se encuentran referencias de la aparición de nuevas versiones de transputers después de 1991.

 

COMPARACIÓN CON OTRAS FAMILIAS DE MICROPROCESADORES

Los transputers son procesadores muy potentes, comparándose incluso con máquinas actuales, como el Pentium, el PowerPC o el cercano P6, quedan en muy buen lugar.

He aquí una gráfica comparativa con otros microprocesadores. Hay que tener en cuenta que hablamos de un sólo transputer en la comparativa, sistemas con varios transputers trabajando en paralelo darán una potencia muy respetable y, por supuesto, muy superior a la de uno solo.

Comparativa de velocidad de varios procesadores en MIPS.

 


 

2.   REDES DE TRANSPUTERS

 

COMUNICACIÓN ENTRE PROCESOS

La comunicación entre los procesos se lleva a cabo usando los canales. Dicha comunicación es punto a punto, sincronizada y no se usan buffers. Por tanto, los canales no necesitan colas de procesos, de mensajes o buffers de mensajes.

Que esta operación sea sincronizada implica que el primer proceso en estar listo tendrá que esperar a que el otro proceso también lo esté.

Dentro de un mismo transputer, dos procesos definen un canal de comunicación entre ellos como una palabra de memoria. Para dos transputers distintos se implementará por enlaces punto a punto, de los que se hablará más adelante.

Existen dos instrucciones que son usadas a la hora de enviar mensajes a través de un canal y se tratan de input message y output message. Ambas instrucciones usan las direcciones del canal para determinar si el canal es interno o externo. Así una secuencia de instrucciones puede ser usada para ambos sin importar, a la hora de escribir y compilar el proceso, los tipos de canales a los que va a ser conectado.

El proceso cuando está listo coloca en la pila de evaluación un puntero al mensaje, la dirección del canal y el número de bytes a ser transferidos. Una vez hecho esto, ejecutaría una de las instrucciones antes descritas. Cuando el otro proceso esté listo comenzará la transmisión. En caso de no estar listo el canal, el proceso se desconectaría.

 

Comunicación usando canales internos

Un canal interno no es más que una palabra reservada en memoria, una variable de paso. Su contenido o bien es un valor que identifica a algún proceso, o bien está vacío. El canal siempre será inicializado a vacío antes de ser utilizado.

Cuando se pasa un mensaje a través del canal, la identidad del primer proceso en estar preparado, no importa que sea el de entrada o el de salida, se guarda en el canal y el procesador comienza a ejecutar el siguiente proceso de la lista. En el momento en que el segundo proceso está listo para usar el canal, el mensaje es copiado, el proceso es añadido a la lista, y el canal se pone a su estado inicial.

Supongamos un determinado proceso P que va a ejecutar una instrucción de salida sobre el canal C que está vacío. Entonces la pila de evaluación contendrá lo antes descrito.

Salida a un canal vacío.

 

Tras ejecutar la instrucción de salida, el canal C contendrá la dirección del espacio de trabajo de P, y la dirección del mensaje a ser transferido se guardará en dicho espacio de trabajo. En ese momento P se desconecta y pasaría a ejecutarse el siguiente proceso.

El canal contiene la identificación del proceso.

 

Tanto el canal como el proceso seguirán es ese estado esperando a que un segundo proceso, Q, ejecute una instrucción de salida en el canal.

Aparece el siguiente proceso.

 

El mensaje es copiado, el proceso P es añadido a la lista, y el canal C es reseteado a su estado inicial.

El canal vuelve a quedarse vacío.

 

Comunicación usando canales externos

En este caso los links son las vías utilizadas para comunicar dos procesos. El interfaz del enlace es el encargado de realzar el proceso de transferir el mensaje y desconectar el proceso. Cuando el mensaje ha sido transferido el interfaz le indica al procesador que vuelva a activar el proceso de espera. Así el procesador puede mantener la ejecución de otros procesos mientras los mensajes externos son transferidos.

La interfaz utiliza tres registros: un puntero al espacio de trabajo del proceso, un puntero al mensaje y un contador del tamaño en bytes del mensaje.

Supongamos que los procesos P y Q en diferentes transputers se comunican por el canal C, implementado por un enlace entre los dos microprocesadores. P envía datos y Q los recibe.

Comunicación entre transputers.

 

Cuando P ejecute su instrucción de salida, los registros en el interfaz del transputers que ejecuta P se inicializan, y P es desconectado. Igualmente, cuando Q realiza su instrucción de entrada, los registros en el interfaz de su transputer se inicializan, y Q se desconecta.

Los procesos se comunican.

 

El mensaje se ha copiado a través del link, después de esto P y Q vuelven a las listas. Con el protocolo empleado se asegura que no tenga importancia el orden de quién esté preparado en primer lugar.

Los procesos vuelven a sus listas.


Enlaces

Los enlaces o links son la puerta de conexión de los transputers con el exterior. Todos los componentes electrónicos de esta familia de INMOS tienen al menos uno de estos, teniendo cada transputer cuatro links. Basándonos en esta filosofía de interconexión pueden obtenerse estructuras topológicas muy complejas.

El uso de este tipo de enlaces son punto a punto y tienen ciertas ventajas respecto a los buses multiprocesadores como la inexistencia de mecanismos de contienda por el acceso al bus, un número alto de microprocesadores no sobrecargaría el sistema y, además, el ancho de banda de las comunicaciones no saturaría al aumentar el tamaño del sistema. En este último aspecto, más bien sería al contrario, pues al ser los enlaces punto a punto, a más conexiones, mayor será el ancho de banda total en el sistema.

Físicamente los links serían dos cables, uno que sería la señal de entrada y otro la de salida, usándose como señal de tierra la masa del sistema. El que sólo haya un cable en cada sentido indica que las señales van a ser transmitidas vía serie.

Los canales serie son de muy alta velocidad, estando estandarizadas las velocidades de 5, 10 y 20 Mbits por segundo, siendo esta última, evidentemente, la más usada. Aunque la única a la que podemos estar seguros que soportará cualquier producto compatible con los transputers será la de 10 Mbits por segundo.

Para que exista alguna sincronización en la comunicación, cada mensaje debe de ser asentido.

El protocolo es simple, el mensaje enviado es un byte de datos o de señales de control al que se le añade una cabecera de dos bits a uno, en niveles TTL, y al final se le añade un cero como bit de parada. Ello implica que el link receptor sólo necesitaría un buffer de un byte para guardar la información. El mensaje de asentimiento implicaría que el link está preparado para recibir otro dato. Éste consiste en dos bits: el primero a uno y el segundo a cero.

Protocolos en los links.

 

El proceso que envía datos sólo saldrá de la lista de procesos activos una vez el link haya recibido el asentimiento.

Para mantener una transmisión continua de datos, el receptor mandaría su asentimiento en cuanto son recibidos los primeros bits de datos.

Transmisión continua.

 

La comunicación a través de los links es independiente de la fase del reloj.

 

Paralelismo


Conceptos sobre paralelismo

Debido a su peculiar manera de gestionar procesos y a sus enlaces de alta velocidad, podemos empezar a hacernos una idea de la capacidad de implementar sistemas paralelos basados en transputers.

El término paralelismo implica muchos conceptos distintos de arquitectura de sistemas informáticos. Las redes de transputers pueden englobarse dentro de las máquinas de paso de mensajes.

Éstas están formadas por una serie de unidades de procesamiento autónomas, en nuestro caso los transputers, denominados nodos y de una red de intercomunicación, constituida por los links. Cada nodo contiene una unidad de proceso, memoria local y hardware específico para la interconexión de los nodos.

Siguiendo la clasificación de Flynn, esta arquitectura se clasificaría dentro del caso MIMD, es decir múltiple flujo de instrucciones y de datos. Cada procesador o nodo por sí sólo suele ser una máquina convencional SISD, de hecho la comunicación entre éstos se dará exclusivamente a través de los enlaces o canales de comunicación de forma que el reparto de la carga lo realizará un único sistema operativo o bien se indicará durante la propia programación del dispositivo. Diremos que la estructura que tenemos en este caso es MIMD de acoplo débil.

Una característica de la arquitectura de paso de mensajes es que la memoria local de cada nodo sólo es accesible por los procesos que se estén ejecutando en éste. Así la acción de compartir información se realizará por paso de mensajes.

La no existencia de una memoria global implicará un aumento en la complejidad de la programación de estos sistemas. Así no se podrá hablar de variables globales, a lo sumo podrá utilizarse algún método que emule la existencia de éstas. Quedará entonces en manos del programador el decidir qué tareas se ejecutan de forma paralela y el reparto de éstas en los procesadores.

Se entiende por granularidad el número de elementos de proceso que componen el sistema paralelo completo. En estos sistemas suele ser de un nivel medio, aunque la tendencia es la de emplear una granularidad fina.

El cuello de botella de estas máquinas es la comunicación entre procesos que estén en distintas máquinas. Esto es debido a dos causas: el número de enlaces de la máquina y la interfase del procesador con la red.

 

Reparto de las tareas

Después de todo lo expuesto surge el problema siguiente: partiendo de un programa compuesto por procesos más simples que interactúan habrá que decidir qué procesador va a ejecutar cada tarea.

El objetivo está muy claro y consiste en minimizar el tiempo de ejecución global del programa. Los dos factores a tener en cuenta son el reparto de la carga de trabajo y el coste de comunicación entre tareas ubicadas en procesadores diferentes.

Así resultará muy importante el repartir las tareas de la forma más eficiente de manera que todos los procesadores estén activos simultáneamente y que todas las tareas acaben a la vez, evitando así tiempos muertos.

Otro detalle a tener en cuenta sería la disposición los procesos de forma que al comunicarse lo hagan a través de nodos adyacentes y eludir así que hayan procesadores que actúen como puentes.

La realidad no permite seguir fielmente estas dos reglas, por una parte porque no es frecuente conocer a priori la duración de los procesos y por otra porque no es posible conocer el momento justo en que las tareas necesiten comunicarse.

 

Ubicación de los transputers

A diferencia de otros microprocesadores, nadie ha desarrollado ordenadores completos basados en los transputers. Éstos suelen ir en módulos independientes denominados TRAM (transputer module) que se conectan a una placa madre que se enchufaría a otro ordenador que actuaría como host. Este host puede ser, según la placa, un compatible PC, una estación SUN o un Macintosh. Debido a que el PC es la plataforma más extendida, vamos a centrarnos en este último.

El modelo de placa madre más usado en los PC es la B008. Ésta se enchufa a cualquier slot del PC y permite la conexión en él de hasta diez TRAM. Cada TRAM integra el procesador, memoria externa (1 o 2 Mbytes normalmente) y dispositivos con los que controlar los links. esta placa dispone de un conector de 37 pines que permite acceder a los links de los transputers enchufados sobre ella.

Placa madre IMS B008

 

Otro modelo de placa madre es la B012. Ambas placas permiten configurar la interconexión entre los transputers de forma que se pueden obtener estructuras de transputers muy interesantes.

 

IMS B008



Estructura pipeline:

Los TRAM conectados sobre el B008 tienen conectados dos de sus links (1 y 2) directamente al siguiente TRAM, de forma que obtendríamos una estructura de elementos en pipeline, así el TRAM número n se conectaría al TRAM n+1 por hardware. Esta forma de conexión se denomina hardwire.

Los otros dos links se conectan a través del C004 que es un dispositivo incorporado a la B008 que programar conexiones entre los links vía software. Este método se denomina softwire.

El C004 está controlado por un transputer que tiene la placa, un T212, a través de su link 3. Éste a su vez recibe los datos por su link 1; por el link 2 tendría un eco de lo que ocurre en el link 3, estando accesible al usuario por la patilla ConfigDown del conector de 37 pines.

El TRAM 0, también llamado host, se comunica por su link 0, a través de un C012, al bus del ordenador y recibe por su link 1 una línea llamada Pipehead. Del link 2 del TRAM 9 saldría la línea Pipetail. El Pipehead puede ser conectado o al C012 de la B008 o al Pipetail de una tarjeta anterior, superando así la barrera física de diez transputers.

Estructura pipeline

Los links 0 y 3 de cada TRAM se utilizan para conectarse a otros TRAM permitiendo construir topologías complejas. La definición de estas conexiones puede hacerla el propio usuario por software, programando el C004. INMOS ha desarrollado el MMS2 que permite definir los enlaces en la placa madre de una forma sencilla a partir de un leguaje propio denominado HL1.

HARDWIRE
  SLOT 0, LINK 2 TO SLOT 1, LINK 1
  SLOT 1, LINK 2 TO SLOT 2, LINK 1
  ...
  SLOT 8, LINK 2 TO SLOT 9, LINK 1

Ejemplo de descripción del hardwire


Relación con el ordenador

El C012 es un circuito integrado que permite adaptar señales procedentes de un bus o canal de ocho bits en paralelo a un link estándar de INMOS. Este integrado es el que utiliza la B008 para conectar el bus del PC al TRAM 0. Precisamente es este enlace el que permite a la red de transputers aprovechar los recursos del PC, como tarjeta gráfica, discos, impresora, etc.

Hay varios tipos de transferencia entre el PC y la placa madre.

El primero de ellos sería un método de polling. Sería el más simple, de hecho modelos más antiguos como el B004 sólo admitían este método de transferencia.

Un método más eficiente es el de acceso directo a memoria o DMA, ello dependerá del chip controlador de DMA usado por el ordenador base, en el caso del PC éste utiliza el 8237.

Una vez inicializado el controlador de DMA, la transmisión puede efectuarse de varios modos. Un ejemplo de transmisión típica sería aquel en la cual un proceso corriendo sobre el TRAM 0 está preparado para enviar y recibir datos sobre su link 0. El programa que corre sobre el PC activaría la transferencia, escribiendo en el registro de control de DMA de la B008. Si la transferencia es del PC a la B008 el valor escrito será un cero y si fuera en dirección contraria se escribirá un uno.

La transferencia tendría lugar cuando el B008 hiciera una petición de DMA, siendo transmitido un byte entre la ejecución de cada instrucción del procesador del PC. Así, el procesador parecería estar ejecutando código mientras la transferencia DMA esté teniendo lugar.

El final de la transferencia se detectaría de una de dos maneras: o bien leyendo el registro de estado del controlador de DMA, sabiendo así qué canales de DMA quedan por transferir y cuáles han acabado, o bien usando una interrupción que señale el fin de la transferencia.

Queda pendiente el tema de las interrupciones. El B008 puede interrumpir al PC en cuatro casos posibles: que haya finalizado la transferencia DMA; que haya ocurrido algún error sobre el B008; o bien que el B008 esté listo para recibir o enviar un byte de datos a través del C012.

 

Diseño de la red

A la hora que diseñar la red es preciso tener en cuenta detalles tan triviales como el número de transputers que disponemos, las exigencias de nuestro programa o nuestra necesidad de potencia de cálculo.

Más importante resulta el problema de la distribución de tareas o el grafo óptimo para que ningún transputer tenga que hacer de puente entre otros dos.

Existe una serie de topologías que son las estándares mostradas en los libros de texto, como la red cuadrada, la cúbica o el grafo de Petersen.

La estructura más común sin embargo es una tipo pipeline donde por softwire se interconecten los transputers donde se suponga que vaya a haber la necesidad de intercambiar información. Es evidente que no se van a conseguir estructuras tan simétricas como las descritas a continuación pero la mayoría de las veces resultarán eficientes.

 

Nodo de transputer

La estructura mostrada a continuación consta de cuatro transputers interconectados de forma que dejan cuatro enlaces libres, así esta estructura puede sustituir a un sólo transputer sin modificar la estructura general de la red.

Nodo de transputer.

 

Red cuadrada:

Esta topología utiliza cuatro TRAM, los número 1, 2, 5 y 6. Para que esta estructura sea realizable sobre la B008, el link 2 del TRAM 2 y el enlace 1 del TRAM 5 han de ser conectados directamente usando un cable.

Estructura cuadrada.

Obsérvese que las líneas discontinuas indican las conexiones por software, que quedarían descritas en el siguiente listado:

SOFTWIRE
  SLOT 1, LINK 3 TO SLOT 6, LINK 0
  SLOT 1, LINK 0 TO EDGE 0
  SLOT 2, LINK 0 TO EDGE 1
  SLOT 2, LINK 3 TO EDGE 2
  SLOT 5, LINK 0 TO EDGE 3
  SLOT 5, LINK 3 TO EDGE 4
  SLOT 6, LINK 3 TO EDGE 5
END

Descripción red cuadrada

 

Red cúbica:

Esta estructura es más compleja, requiere ocho TRAM y el esquema sería como el que sigue:

Estructura cúbica.

Su descripción softwire vendría dada por:

SOFTWIRE
  SLOT 1, LINK 0 TO SLOT 4, LINK 3
  SLOT 2, LINK 0 TO EDGE 0
  SLOT 3, LINK 0 TO EDGE 1
  SLOT 4, LINK 0 TO EDGE 2
  SLOT 5, LINK 0 TO SLOT 8, LINK 3
  SLOT 6, LINK 0 TO SLOT 3, LINK 3
  SLOT 7, LINK 0 TO SLOT 2, LINK 3
  SLOT 8, LINK 0 TO SLOT 1, LINK 3
  SLOT 5, LINK 0 TO EDGE 3
  SLOT 6, LINK 0 TO EDGE 4
  SLOT 7, LINK 0 TO EDGE 5
END

Descripción de la estructura cúbica.

 


 

3.  OCCAM


Lenguaje procedimental:

Debido a la peculiar filosofía de funcionamiento de los transputers cabría esperar que su programación en alto nivel fuese diferente.

Está claro que los lenguajes de programación convencionales, como Fortran, Pascal o C, se han desarrollado pensando en los marcos de una arquitectura de ordenador convencional, basada en un único procesador secuencial y en las aplicaciones convencionales que requiere el proceso de datos.

En el mundo de la informática siempre se ha dicho que el software va invariablemente detrás del hardware y que es el verdadero cuello de botella del desarrollo del mundo de los ordenadores. Ahora esta frase es una realidad que nos obliga a pensar en las características de un lenguaje de programación a la altura de las nuevas tendencias a la hora de desarrollar sistemas informáticos.

Las características que debe de cumplir cualquier lenguaje orientado a implementar procesos concurrentes se resumen en:

  • Un estructura global clara en términos de módulos, llevando a cabo cada módulo una tarea específica.

  • Una interfase entre módulos perfectamente definida.

  • Cada módulo debe de ser una combinación simple de construcciones elementales del lenguaje de programación.

  • Es esencial alcanzar un alto grado de correspondencia entre la estructura de programa de un módulo y la estructura de los datos con que opera.

  • Cada módulo debe dejar la estructura sobre la que opera en un estado que sea consistente con las propiedades que tiene definidas.

  • La operación de un módulo en concreto no debe de tener efectos laterales, no debe alterar ningún dato fuera de su zona de actuación.

Los lenguajes de programación pueden ser procedimentales o no procedimentales; los procedimentales agrupan a los convencionales y a sus derivados, se distinguen por describir, con exhaustivo detalle, los pasos que el ordenador debe llevar a cabo para realizar una tarea de proceso de datos en particular.

Los no procedimentales se basan en la descripción de lo que se necesita para el proceso de una tarea y la estructura de datos de dicha tarea, dejando al procesador del lenguaje los detalles de cómo se deben realizar la tarea.

Los lenguajes procedimentales han evolucionado o bien tomando el apellido "concurrente", como Pascal concurrente o C concurrente, o bien como lenguajes como Ada o el Occam, siendo este último el elegido por INMOS para sus transputers.

 

Occam

Occam es un lenguaje de programación diseñado para soportar procesos concurrentes en sistemas informáticos, en donde muchos elementos de proceso operen independientemente, pero interactivamente.

Este lenguaje fue desarrollado por Tony Hoares, de la Universidad de Oxford, y fue tomado como el estándar de programación de los transputers.

Occam se basa en la idea de procesos secuenciales que se comunican. Un proceso realiza una secuencia de acciones y se comunica con otros procesos a través de los canales. La filosofía de dicha comunicación es la del transputer: cuando los procesos de entrada y de salida están preparados para comunicarse en el mismo canal, los datos se transfieren y los procesos continúan independientemente.

Se trata de un lenguaje simple en cuanto al número de palabras reservadas que no supera las treinta, y al pequeño número de estructuras del que dispone. Aunque cada proceso emplea asignaciones destructivas, es decir los valores de los datos al comienzo del programa, una vez establecidos, pueden cambiar durante la ejecución de éste, el uso de canales para comunicación entre procesos le hace enteramente consistente con arquitecturas de flujo de datos y reducción de grafos.

 

Descripción del lenguaje


Asignación

El símbolo de asignación en Occam es := tal como sería en Pascal. Así var := 2 daría a var el valor 2.

También es posible la asignación múltiple; var1, var2 := 2, 3.

 

Procesos de entrada:

Un proceso de entrada asignará el valor leído del canal a una variable. El símbolo utilizado es ?. Por ejemplo canal ? var, asignaría a la variable var el contenido del canal.

Es importante señalar que el proceso de entrada se quedará en espera hasta que reciba una entrada válida por el canal.

 

Procesos de salida:

Sería la operación inversa a la anterior, y el símbolo sería !. Así la línea canal ! 2 , mandaría por el canal el valor 2.

Por un canal pueden mandarse valores, vectores y matrices.

 

Construcciones

Existen varias construcciones en Occam, las principales son SEQ, PAR y ALT. Permiten indicar el grado de concurrencia dentro de los procesos.

SEQ indicaría que no existe ninguna concurrencia entre los procesos señalados (o instrucciones) lo que equivaldría a procesamiento secuencial de las instrucciones.

SEQ
  canal1 ? var
  valor := var + 1
  canal2 ! valor

En este ejemplo, var toma el valor del canal 1, a dicho valor le incrementa 1 y lo deja en la variable valor, mandándola por el canal 2.

Obsérvese que el procesamiento secuencial afectará a todo lo que esté indentado dos espacios tras la orden SEQ.

Si quisiera ejecutar muchas veces las mismas órdenes podría definir bucles usando a estructura SEQ i = 0 FOR n.

PAR indicará paralelismo en las acciones posteriores. Por ejemplo:

PAR
  SEQ
    canal3 ? var
    var := var + 1
  SEQ
    canal4 ? valor
    valor := valor + 1

Donde los valores de los canales 3 y 4 serán introducidos independientemente en cada variable, de forma que los procesos de lectura del canal y de incremento del valor se realizarán en paralelo.

Supongamos que se diera el caso que el canal 3 no recibiera ningún dato, pero sí el canal 4. Entonces var no sería incrementado, pero ello no impediría que lo fuera valor, puesto que ambos procesos son paralelos e independientes. Habrá que tener cuidado con no utilizar la misma variable o el mismo canal en dos procesos que se ejecuten a la vez pues en otro caso habrán conflictos.

Los bucles en paralelo se indican igual que los secuenciales: PAR i = 0 FOR n.

En el caso de ser ejecutados los procesos en transputers distintos, la disposición de dichos procesos ha de ser especificada con el comando PLACED PAR.

ALT permite construcciones alternativas, parando la ejecución de un proceso concurrente hasta que algunas de las sentencias de esta construcción puedan usarse.

La estructura de ALT sería algo como lo siguiente:

ALT
  entrada 1
    P1
  entrada 2
    P2
  entrada 3
    P3
  ...

De forma que el proceso que se ejecutaría sería el primero en recibir la entrada. En caso de ocurrir en varios a la vez, la elección es aleatoria.

También existen las estructuras IF, WHILE y CASE, similares a las existentes en otros lenguajes de programación.

 

Variables y canales

Los tipos de variables definidos en Occam son, fundamentalmente, INT (entero), BYTE (de 0 a 255) y BOOL (0 ó 1).

Han de ser obligatoriamente definidos a comienzo de la función o del procedimiento, siguiendo la sintaxis INT valor, val:.

Los canales se definirían de la misma forma, de manera que un canal una vez definido para un determinado tipo sólo puede utilizarse para mandar ese tipo de datos y no otro distinto. CHAN OF INT canal3:.

 

Procesos y funciones

Son similares a las existentes en otros lenguajes, distinguiéndose la posibilidad de declarar como parámetros canales además de las variables. Las palabras reservadas serían PROC y FUNCTION.

 

La importancia del indexado

El indexado es fundamental para que el compilador entienda nuestros programas. Ha de ser de dos espacios e indica que todo lo que esté al mismo nivel está afectado por la misma estructura, PAR, SEQ, etc.

 

Un ejemplo

Un ejemplo de programa en Occam sería el siguiente:

PAR
  WHILE TRUE
    INT x1:
    SEQ
      chan1 ? x1
      chan2 ! x1*x1
  WHILE TRUE
    INT x2, y2:
    SEQ
      chan3 ? x2
      chan4 ? y2
      chan5 ! x2/y2
  WHILE TRUE
    INT x3:
    SEQ
      ALT
        chan6 ? x3
          SKIP
        chan7 ? x3
          SKIP
      chan8 ! x3

El programa se compone de tres procesos paralelos de forma que el primero esperaría a recibir por chan1 un dato y lo mandaría luego por chan2 multiplicado por sí mismo. El segundo proceso esperaría dos datos y luego enviaría el resultado de dividir uno por otro por chan5. El último proceso esperaría recibir algún dato por uno de los dos canales, chan6 o chan7, una vez recibido enviaría el valor a través de chan8.

Esto se ve claramente en el siguiente gráfico:

Procesos en Occam

 


 

4. ENTORNO DE DESARROLLO


El entorno de desarrollo que se entrega junto a los transputers es el TDS que responde a las siglas Transputer Development System.

Se trata de un sistema de desarrollo de aplicaciones, basado en Occam, que reúne herramientas como un editor, un compilador de Occam y un depurador.

 

Editor

Como el resto de este entorno de desarrollo, el interfase hacia el usuario es poco agradable, fruto de un diseño típico de los ochenta, donde el usuario era el que tenía que adaptarse al ordenador.

Este editor es muy incómodo pues requiere la utilización de una gran cantidad de teclas para cada cosa.

Impone la utilización de folders, que son bloques de listado representados por una sola línea, que se identifica al comenzar por tres puntos. El manejo del TDS se basa en navegar entre folders. Para ello existen teclas para entrar y salir de ellos, así como para moverlos, borrarlos, etc.

 

Compilador

Existen cinco tipos de unidades o folders de compilación:

  • EXE: programa ejecutable desde TDS.

  • UTIL: programa con utilidades especiales a ser utilizadas por otros programas.

  • PROGRAM: preparado para ejecutarse sobre un red de transputers. Contiene información sobre la configuración que permite al sistema de desarrollo cargar el programa sobre dicha red.

  • SC: unidad de compilación separada. Suele contener procedimientos y funciones de Occam.

  • LIB: librerías. TDS ofrece una extensa gama de librerías para ser usadas por el desarrollador de aplicaciones en Occam.

Habrían tres formas de ejecutar un programa en Occam:

  • Dentro de TDS para un transputer.

  • Dentro de una red de transputers.

  • Fuera de TDS.

En el primer caso habría que realizar lo siguiente:

  1. Chequeo de sintaxis.

  2. Compilación, linkado y generación del código ejecutable, EXE.

  3. Cargar el código en la red de transputers.

  4. Ejecución propiamente dicha.

Si el programa ya había sido previamente compilado bastaría con realizar los pasos 3 y 4.

En el segundo caso habría que comenzar realizando los pasos 1 y 2 también sobre el PROGRAM en el que figuraría la descripción del reparto de tareas entre los distintos transputers, así como el encaminamiento a seguir del flujo de datos. Siempre, antes de ejecutar el programa, habrá que cargar la red, es decir decirle a cada transputer qué tiene que hacer cuando se le diga que comience con su tarea.

Un ejemplo PROGRAM para cargar un sistema de ocho nodos en pipeline, siete de los cuales contienen el mismo programa:

{{{  PROGRAM pipeline
{{{F source
... SC element (CHAN OF INT32 in, out, VAL INT board.no)
... SC element (CHAN OF INT32 in, out, VAL INT board.no)

VAL last IS 7:
VAL input.links IS [5, 7, 6, 7, 5, 7, 6, 7] :
VAL output.links IS [0, 2, 1, 1, 0, 2, 1, 1] :

[last+1]CHAN OF INT32 links :

PLACED PAD
  PROCESSOR T4
    PLACE links[last]  AT  input.links[0] :
    PLACE links[0]  AT  output.links[0] :

    pipe.end (links[last], links[0], 0)

  PLACED PAR i=1 FOR last
    VAL in IS i-1:
    VAL out IS i:
    PROCESSOR i T4
      PLACE links[in] AT input.links[i] :
      PLACE links[out] AT output.links[i] :
      element (links[in], links[out], i)
}}}
}}}  

Obsérvese como para cada link se diferencia el canal de entrada y el de salida de forma que la numeración es número de link para links de salida y número de link más cuatro para links de entrada.

El compilador es muy poco tolerante a errores, lo cual significa que el programador puede perder varias horas por culpa de una conversión de tipos mal hecha.

 

Depurador:

Sólo permite realizar lo que podríamos denominar un análisis post-morten. Analizando el fichero code dump donde se ha volcado el estado de las variables del sistema en el instante del "cuelgue".

 


 

5. APLICACIONES


Aplicaciones típicas:

El número de aplicaciones para máquinas de tal potencia es algo abierto a la imaginación de los desarrolladores.

INMOS propone la siguiente lista de aplicaciones:

  • Aplicaciones científicas y matemáticas. Éstas requieren grandes cantidades de cálculos antes reservadas a las grandes computadoras.

  • Sistemas multiprocesadores de alta velocidad.

  • Procesamiento gráfico de alto rendimiento. Con treinta y dos transputers se conseguiría la misma potencia que la de los superordenadores vectoriales usados para generar secuencias de animación para películas. Sirva de ejemplo que con cuatro transputers se podrían generar animaciones a base de polígonos, unos doscientos, de 17 imágenes por segundo.

  • Supercomputadores. Ya se comentó al principio que con cierto número elevado de transputers se conseguiría alcanzar potencias comparables a la un Cray. Conviene tener en cuenta el siguiente dato: el Cray 3, la máquina más potente jamás construida da una potencia de cálculo de más de 16000 MIPS.

  • Estaciones de trabajo basadas en transputers.

  • Procesamiento digital de señales. Así se entra en competencia con los DSP, debido a los canales de alta velocidad se pueden realizar adquisiciones de señales a muy altas velocidades.

  • Bases de datos distribuidas.

  • Simulación de sistemas.

  • Telecomunicaciones.

  • Robótica. Usando los transputers como procesadores de los sistemas de control.

  • Procesamiento de imágenes.

  • Reconocimiento de patrones. Permitiendo la implementación software de sistemas de clasificación tales como redes neuronales.

  • Inteligencia artificial. De hecho algunos autores consideran Occam como un lenguaje de la Quinta Generación.

Arquitecturas similares

Se puede hablar de dos sistemas que ofrecen computación paralela a bajo costo:

  • Hipercubos de Intel.

  • Las últimas generaciones de DSP.

Los hipercubos de Intel son estructuras basadas en 80386 con coprocesador, memoria local de hasta 16 Mbytes, un interfase para añadir dispositivos al nodo y un módulo de encaminamiento, DCM, que gestiona ocho canales serie, de forma que al dedicar siete de éstos para las conexiones con otros nodos, se obtiene un hipercubo de 128 elementos. Intel denomina a esta arquitectura iPSC/2 (existió la iPSC/1 más antigua). Su similitud con el transputer es alta; aunque aquí el tema del encaminamiento y la gestión de los procesos la realiza un sistema operativo, NX/2, que reside en cada nodo. La arquitectura del transputer es específica para su conexión en paralelo, mientras que iPSC/2 consiste en poco más que un circuito basado en un 80386 al que se le han añadido capacidad de interconexión. Por último habría que comentar la diferencia en la potencia de los dos micros: un transputer suele alcanzar los 30 MIPS, mientras que un 80386 apenas va a llegar a los 5 MIPS. Los DSP están teniendo mucho éxito en los últimos años debido al desarrollo de estos por algunas marcas como Texas Instruments, Zilog o SGS-Thomson. La descripción más simple de un DSP es la de un microprocesador preparado para capturar señales de muy diversos tipos y a altas velocidades. Los C40 de Texas Instruments, que son DSP tienen cuatro canales bidireccionales de alta velocidad que podrían usarse como links. Aunque no estén estos dispositivos preparados para el procesamiento en paralelo internamente, su capacidad de interconectividad los hace muy indicados para el desarrollo de sistemas concurrentes. Asimismo la capacidad de cálculo de un DSP puede ser de unos 20 MIPS en el C40 y superior en modelos más avanzados, así que sólo es cuestión que alguien se dedique ha formar redes de DSP para procesamiento en paralelo. 

Futuro

Por último quedaría por platearse si los transputer tienen algún futuro. Ya en la introducción se comentó las pocas intenciones por parte de INMOS de continuar con el desarrollo de estas máquinas.

A principio de los noventa se habló mucho sobre el nuevo H1, sobre todo porque solucionaba el problema del encaminamiento, el talón de Aquiles de los transputers, a través de su C104 que estaba dedicado a dicho menester. Cada C104 permite conectar hasta 32 H1 y ejecuta un algoritmo de encaminamiento programable siendo la topología de la red.

Sin embargo, en los dos últimos años nadie parece querer hablar sobre ellos. De todas formas, el hecho que aún haya quien utilice los transputers indica que, al menos, fueron una buena idea.