Consideremos un algoritmo (por ejemplo, el cifrado) que tiene 8 pasos estrictamente idénticos (la salida se usa como entrada del siguiente paso).
Teniendo en cuenta que tengo suficientes recursos para poner 8 "módulos de pasos" en mi placa, me pregunto cuáles son las ventajas de hacerlo como una tubería (8 módulos conectados en línea con algunos búfer en el medio) o como 8 módulos separados (con un bucle sobre sí mismo a través del multiplexor y el búfer).
Si tengo un puerto de entrada para proporcionar los datos para cifrar, el rendimiento no debería cambiar, la latencia general y el rendimiento serán los mismos .
simular este circuito : esquema creado con CircuitLab
En la parte superior: la tubería, debajo del paralelo (considerando solo 2 veces a través del "módulo de pasos" y omitiendo los búferes)
¿Hay alguna diferencia significativa?
Exploración adicional: ¿qué sucede si no tengo suficiente espacio para 8 módulos (pero quizás solo 7) o para más de 8 (quizás 9)?
Tiene un módulo que debe procesar los datos varias veces seguidas para completar la conversión. En el ejemplo 'canalizado', simplemente alimenta cada uno a su vez. Esto tendrá cierta latencia ya que los datos tardan un tiempo en pasar de la entrada a la salida. Sin embargo, si los bloques están realmente canalizados, esto es solo una latencia: puede ingresar una nueva palabra de datos en cada ciclo, y habrá múltiples muestras en la etapa de canalización en cualquier punto dado, lo que permitirá el mismo rendimiento al final.
Su caso 'paralelo' no es realmente un caso paralelo. Es básicamente el mismo caso canalizado, pero en lugar de pegarlos uno tras otro, termina con una lógica adicional para distribuir los datos entrantes a cada bloque, y luego, presumiblemente, cada bloque tiene más lógica para retroalimentar su salida a través de sí mismo suficientes veces para completar la conversión. Al final tienes que recombinarlos todos. Es básicamente un método feo de hacer un cálculo canalizado.
No estoy seguro de dónde saca la idea de que su tubería debe tener 2,4,8,16 unidades. Si necesita procesar los datos a través del módulo 7 veces, simplemente colocaría 7 seguidos en la canalización: cada uno opera en la salida del último, por lo que no importa si no es una potencia de dos longitudes. .
Una versión verdaderamente paralela sería aquella en la que el cálculo se puede dividir en operaciones parciales. Digamos, por ejemplo, que desea multiplicar dos números de 16 bits, pero solo tiene un bloque multiplicador de 8x8 que tarda un ciclo de reloj en completarse. Podría colocar 4 en serie y tener algo de acumulación (esta sería una operación canalizada), o podría agregar varias instancias del multiplicador y ponerlas en paralelo. En paralelo, el resultado tendría una latencia de 1 ciclo de reloj, en canalización (serie) tendría una latencia de 4 ciclos. Esto tiene el costo de usar 4 veces más lógica.
Otro ejemplo de comportamiento paralelo verdadero es si necesita procesar varias palabras a la vez, y más rápido de lo que podría manejar un bloque. Digamos que tenía un bloque que tomó una palabra de datos y la encriptó. El bloque solo puede manejar una palabra en su entrada en cada ciclo de reloj. Ahora, ¿qué sucede si su flujo de datos entrante consta de cuatro palabras que llegan todas en el mismo ciclo de reloj, pero su bloque de cifrado solo puede manejar una a la vez? El rendimiento del módulo de cifrado es 1/4 de lo que se requiere. Ahora, si coloca cuatro bloques en paralelo, ahora puede procesar cada una de las cuatro palabras al mismo tiempo, lo que permite el rendimiento requerido, nuevamente a expensas de requerir cuatro veces más lógica.
Hay un caso en el que el segundo enfoque está realmente justificado. Digamos que necesita procesar cada palabra a través de la etapa de cálculo 8 veces, pero debido al tamaño del cálculo, solo tiene espacio en el FPGA para, digamos, 3 pases, luego necesitaría una forma de reutilizar el recurso. Está tratando de romper el cálculo para usar menos bloques.
En esta situación, sí, tener lógica para retroalimentar el mismo bloque varias veces es bastante ventajoso. Esto le permite reutilizar el mismo módulo y muchos menos recursos lógicos para procesar el cálculo. Sin embargo, esto se produce a expensas del rendimiento. Si necesita pasar la misma palabra de datos a través del mismo bloque 8 veces, entonces su rendimiento se reduce a un octavo, porque mientras lo hace, ninguna palabra nueva puede ingresar al bloque.
Tener espacio para bloques adicionales (digamos 3) le permitiría realizar el cálculo en paralelo para tres palabras de datos a la vez. Usted instancia tres copias de su circuito de bloque único y agrega algo de lógica adicional para determinar cuándo es el momento de que una nueva palabra ingrese a cada uno de los bloques. Esto, a su vez, recupera algo de rendimiento: ahora es 3/8 de lo que era.
Puedo actualizar la respuesta con algunos diagramas si es necesario, pero espero que la explicación sea bastante clara.
En palabras simples, una sola canalización solo hará UNA cosa a la vez. Si tiene módulos en serie, cada módulo tendrá que esperar a que se complete el módulo anterior.
Dado que todos los pasos son idénticos, esto solo será un problema hasta que la canalización esté llena.
Si se hace en paralelo, se anulará esta penalización inicial.
Estas son las diferencias que se me ocurren (después de escribir la pregunta y editarla de acuerdo con los comentarios):
La versión paralela necesitará más lógica (multiplexores) para enviar la entrada y realizar un seguimiento de cuántas veces los datos ya pasaron por el módulo.
Pero la versión paralela también admite un número arbitrario* de "módulo de pasos" (por ejemplo, 7 de 9), mientras que la canalización no es tan flexible (depende estrictamente de los requisitos del algoritmo).
*teniendo en cuenta que mi algoritmo requiere 8 pasos, pero mi FPGA quizás solo tenga lugar para 7 (o 9) módulos de pasos, puedo hacer 7 (o 9) versiones paralelas y el rendimiento aumentará en consecuencia.
Andy alias
Andy alias
tom carpintero
Andy alias
tom carpintero
tom carpintero
oliverpool
tom carpintero
oliverpool