Arquitectura de flujo de datos
La arquitectura de flujo de datos es una arquitectura de computadores que contrasta directamente con la tradicional Arquitectura de Von Neumann o de estructuras de control. Las arquitecturas de flujo de datos no se basan en un contador de programa (al menos conceptualmente) en tanto en cuanto la posibilidad de ejecución de las instrucciones solamente viene determinada por la disponibilidad de los argumentos de entrada de las instrucciones. Aunque ningún computador de éxito comercial ha utilizado este tipo de arquitectura, esta es muy relevante en muchas arquitecturas actuales de software, incluyendo el diseño de sistemas de bases de datos o de sistemas de procesamiento paralelo.
Este tipo de arquitecturas de hardware constituyó una de las principales ramas de investigación sobre arquitectura de computadores en los años 70 y principios de los 80. Jack Dennis del MIT abrió el camino en el campo de las arquitecturas de flujo de datos estático, mientras que la Manchester Dataflow Machine y la arquitectura MIT Tagged Token fueron algunos de los mayores proyectos en flujo de datos dinámico.
Los diseños que emplean direcciones convencionales de memoria como marcas de dependencias de datos son conocidos como máquinas de flujo de datos estático. Estas máquinas no permitían la ejecución simultánea de varias instancias de una misma subrutina porque la forma de etiquetar los datos no diferenciaba entre ellas. Aquellos diseños basados en memoria de contenido direccionable o CAM son llamados máquinas de flujo dinámico de datos.
Normalmente, los compiladores analizan el código fuente del programa en busca de dependencias de datos entre instrucciones para organizar mejor la secuencia en los ficheros binarios de salida. Las instrucciones son organizadas de forma secuencial, pero la información acerca de las dependencias no se graba en los binarios. Sin embargo, los ficheros binarios compilados en una máquina de flujo de datos sí contienen esta información. Un compilador de flujo de datos graba estas dependencias creando etiquetas únicas para cada dependencia en lugar de utilizar nombres variables. Al nombrar cada dependencia de forma unívoca, se consigue que los segmentos de código no dependientes en el fichero binario sean ejecutados sin problemas fuera de orden o en paralelo.
Los programas se cargan en la memoria CAM del computador de flujo dinámico. Cuando todos los operandos etiquetados de una instrucción pasan a estar disponibles (esto es, han recibido la salida de instrucciones previas y/o la entrada de usuario), la instrucción se marca como preparada para su ejecución. Este proceso es conocido como activación o firing. Una vez que la instrucción es completada, su salida es almacenada junto con la correspondiente etiqueta en la memoria CAM. Cualquier instrucción que sea dependiente de este dato en concreto (identificado por el valor de su etiqueta) es entonces marcada como preparada para su ejecución. De este modo, las instrucciones subsiguientes son ejecutadas en el orden correcto, evitando la aparición de condiciones de carrera. Este orden puede diferir del orden secuencial considerado por el programador.
Una instrucción, junto con los operandos requeridos, es transmitida a una unidad de ejecución como un paquete, también conocido como señal de instrucción. De forma similar, los datos de salida son transmitidos de vuelta a la memoria CAM como señal de datos. El empaquetado de instrucciones y resultados permite la ejecución paralela a gran escala de instrucciones preparadas. Las redes de flujo de datos reparten las señales de instrucción a las unidades de ejecución y devuelven a la memoria CAM las señales de datos. En contraste con la Arquitectura de von Neumann convencional, las señales de datos no son almacenadas de forma permanente en memoria, sino que son mensajes transitorios que solamente existen durante el tránsito de información que se produce en el almacenamiento de la instrucción.
La investigación, sin embargo, nunca se preocupó de tratar problemas relacionados con:
- Emisión eficiente de las señales de datos e instrucciones en sistemas paralelos masivos
- Construcción de memorias CAM lo suficientemente grandes como para almacenar todas las dependencias de un programa real
Se probó que las instrucciones y sus dependencias de datos eran una unidad demasiado pequeña para trabajar en grandes redes. Esto es, el tiempo de transmisión de las instrucciones y los correspondientes resultados etiquetados era mucho mayor que el tiempo realmente necesario para su procesamiento.
Sin embargo, la ejecución fuera de orden se ha convertido en el paradigma computacional por excelencia desde los años 90. Es una forma de flujo de datos restringido. Este paradigma introdujo la idea de ventana de ejecución, que sigue el orden secuencial de la arquitectura de von Neumann; sin embargo, dentro de la ventana se permite que las instrucciones sean completadas en el orden de las dependencias de datos. Esto se consigue en procesadores que etiquetan dinámicamente las dependencias de datos en la ventana de ejecución. La complejidad lógica de mantener el rastro de las dependencias de datos de forma dinámica restringe a los procesadores basados en ejecución fuera de orden a un reducido número de ejecuciones (de 2 a 6) y limita el tamaño de la ventana de ejecución de 32 a 200 instrucciones, mucho menor que las utilizadas en las máquinas puras de flujo de datos.