¿Qué tan rápido se multiplica o divide una ejecución de 64 bits en un FPGA?

8

Cuando se usa un FPGA normal como Xilinx Spartan 3 o Virtex 5, ¿cuántos ciclos se tarda en ejecutar una multiplicación o división de coma flotante de doble precisión de 64 bits?

Por lo que yo entiendo, el FPGA no tiene un FPU duro y usted necesita crear uno usando las bibliotecas IEEE estándar u otros materiales. Esto significa que no se ejecutará en un solo ciclo, por lo que estoy buscando una estimación aproximada para comparar el rendimiento de una CPU de 100 Mhz con un FPGA Spartan / Virtex de 100 MHz.

Me interesan principalmente los operadores de punto flotante, pero si tiene experiencia con operaciones de enteros, eso también sería apreciado.

El flash
fuente
3
Primero, vale la pena aclarar la pregunta: usted habla de MPY / división de 64 bits, lo que implicaría multiplicación / división de enteros de 64 bits, luego menciona FPU, que implica punto flotante de doble precisión. Los detalles de la respuesta serán diferentes para cada ...
Brian Drummond
2
Para una multiplicación a la vez, el tiempo es probablemente comparable o ligeramente a favor de la CPU. Obviamente, la ventaja del FPGA es que puede tener muchos de ellos en paralelo.
pjc50

Respuestas:

12

No he hecho esto para FP de doble precisión, pero se aplican los mismos principios que para precisión simple, para lo cual he implementado división (como multiplicar por recíproco).

Lo que estos FPGA tienen, en lugar de FPU, son bloques DSP / multiplicadores cableados, capaces de implementar una multiplicación 18 * 18 o (Virtex-5) 18 * 25 en un solo ciclo. Y los dispositivos más grandes tienen alrededor de mil de estos, o incluso 126 o 180 en el extremo superior de las familias Spartan-3 o Spartan-6.

Por lo tanto, puede descomponer una gran multiplicación en operaciones más pequeñas usando varias de estas (2 para el Virtex-5 haciendo precisión simple) usando los sumadores del DSP o la estructura FPGA para sumar los productos parciales.

Obtendrá una respuesta en unos pocos ciclos: 3 o 4 para SP, quizás 5 para DP, dependiendo de cómo componga el árbol sumador (y, a veces, donde las herramientas de sintetizador insisten en agregar registros de canalización).

Sin embargo, esa es la latencia: a medida que se canaliza, el rendimiento será de 1 resultado por ciclo de reloj.

Para la división, aproximé un operador recíproco usando una tabla de búsqueda seguida de interpolación cuadrática. Esto era más preciso que la precisión simple y se extendería (con más hardware) a DP si quisiera. En Spartan-6 se necesitan 2 BlockRams y 4 DSP / multiplicadores, y un par de cientos de pares LUT / FF.

Su latencia es de 8 ciclos, pero nuevamente el rendimiento es de ciclo único, por lo que al combinarlo con el multiplicador anterior, obtienes una división por ciclo de reloj. Debe superar los 100MHz en Spartan-3. En Spartan-6, la estimación de síntesis es de 185MHz, pero eso es con 1.6ns en una sola ruta de enrutamiento, por lo que 200MHz está dentro de lo razonable.

En Virtex-5 alcanzó 200MHz sin esfuerzo, al igual que su gemelo de raíz cuadrada. Tuve un par de estudiantes de verano que intentaron volver a canalizarlo: con una latencia de menos de 12 ciclos, se acercaron a 400MHz, 2.5 ns para una raíz cuadrada.

¿Pero recuerda que tiene quizás entre cien y mil unidades DSP? Eso le da a uno o dos órdenes de magnitud más poder de procesamiento que una sola unidad FP.

Brian Drummond
fuente
Gracias por tu respuesta, Brian, pero ¿no es toda tu respuesta sobre la multiplicación / división de enteros? Estoy principalmente interesado en coma flotante.
TheFlash
2
No, como dije, precisión simple, que significa punto flotante de 32 bits. Los mismos principios se aplican a los dobles, pero el uso de recursos es obviamente mayor.
Brian Drummond
5

Cuando se usa un FPGA normal como Xilinx Spartan 3 o Virtex 5, ¿cuántos ciclos se tarda en ejecutar una multiplicación o división de coma flotante de doble precisión de 64 bits?

¡La respuesta es sí!

Pero en serio, es muy difícil encontrar un número. Al diseñar cualquier lógica compleja, siempre hay una compensación entre diferentes cosas, y ningún enfoque es bueno para todos los diseños. Trataré de cubrir los grandes.

Con el diseño lógico, una compensación es el tamaño frente a la velocidad. El ejemplo fácil de esto es, digamos, que un único multiplicador de punto flotante es demasiado lento. Para acelerarlo todo lo que tienes que hacer es agregar un segundo multiplicador. Su tamaño lógico se duplica, pero lo hace el número de multiplicados por segundo. Pero incluso mirando un solo multiplicador, hay diferentes formas de multiplicar números; algunos son rápidos y grandes, otros son pequeños y lentos.

Otra compensación es la velocidad del reloj frente a los relojes por multiplicación. Podría diseñar alguna lógica que haga que un punto flotante se multiplique en un reloj. Pero eso también requeriría que el reloj sea más lento, tal vez tan lento como 10 MHz. O podría diseñarlo para que funcione con un reloj de 100 MHz, pero requeriría 10 relojes por multiplicación. La velocidad general es la misma (una se multiplica en 100 ns), pero una tiene un reloj más rápido.

Relacionado con el párrafo anterior está la compensación de la velocidad del reloj frente a la latencia múltiple. Existe una técnica en el diseño lógico llamada canalización. Básicamente, tomas un trozo de lógica y lo divides en etapas más pequeñas, donde cada etapa toma un ciclo de reloj para completarse. La ventaja aquí es que cada etapa puede estar trabajando en una multiplicación mientras que las otras etapas están trabajando en otras multiplicaciones. Por ejemplo, digamos que estamos funcionando a 100 MHz con una tubería de 10 etapas. Esto significa que tomará 10 relojes por cada multiplicación, ¡pero la lógica también funciona en 10 multiplicaciones diferentes al mismo tiempo! Lo bueno es que está completando una multiplicación en cada ciclo de reloj. Entonces, los relojes efectivos por multiplicación son 1, solo se necesitan 10 relojes para completar cada una de esas multiplicaciones.

Entonces, la respuesta a su pregunta, qué tan rápido puede un FPGA hacer una multiplicación, realmente depende de usted. Los FPGA vienen en diferentes tamaños y velocidades, y puede dedicar tanta lógica a la tarea en cuestión como desee. Pero veamos un escenario específico ...

Digamos que queremos usar el Spartan-3A más grande y todo lo que nos importa son las multiplicaciones de coma flotante de 32 bits. Una multiplicación flotante de 32 bits requiere un multiplicador entero 24x24 y un sumador de 8 bits. Esto requiere cuatro de los bloques multiplicadores dedicados y algunos segmentos genéricos (muy pocos para preocuparse). El XC3S1400A tiene 32 multiplicadores dedicados, por lo que podemos hacer ocho de nuestros multiplicadores de coma flotante en paralelo. Una suposición muy aproximada sobre la velocidad del reloj sería de unos 100 MHz. Podemos canalizar completamente este diseño para poder completar cuatro multiplicaciones de coma flotante de 32 bits por ciclo de reloj, para una velocidad efectiva de 800 millones de multiplicaciones de coma flotante por segundo.

Una multiplicación de doble precisión requiere 9 bloques multiplicadores dedicados por multiplicación de punto flotante, por lo que solo podríamos hacer 3 multiplicaciones en paralelo, lo que da como resultado una velocidad de aproximadamente 300 millones de multiplicaciones de coma flotante de 64 bits por segundo.

A modo de comparación, consideremos la nueva serie Xilinx Virtex-7. Los multiplicadores dedicados son más grandes, por lo que solo necesitamos 6 bloques multiplicadores dedicados para una multiplicación de coma flotante de 64 bits. También hay 1.920 multiplicadores dedicados en la parte más grande, por lo que podemos hacer 320 multiplicadores de coma flotante de doble precisión en paralelo. Esas partes también son mucho más rápidas. Calculo que podemos ejecutar esas partes a 200 MHz, lo que nos da una velocidad total de 64 MIL MILLONES de multiplicaciones de punto flotante de precisión doble por segundo. Por supuesto, esos chips cuestan alrededor de US $ 10,000 cada uno.

La división de punto flotante es mucho más difícil de hacer rápidamente. La lógica es mucho más grande, especialmente en un FPGA, y funciona mucho más lento. Lo mismo es cierto para la mayoría de las CPU, ya que las instrucciones de división (punto flotante y fijo) son mucho más lentas. Si la velocidad es importante, entonces desea eliminar tantas divisiones como sea posible. Por ejemplo, en lugar de dividir por 5, debe multiplicar por 0.2. De hecho, en muchos sistemas es más rápido calcular un recíproco y multiplicar que simplemente dividir.

Las mismas compensaciones se aplican a la división como multiplicación: es solo que la división siempre será mucho más lenta y mucho más grande que la multiplicación.


fuente
Un TI DSP o incluso una GPU en un Rasberry Pi 3 absorberá el humo mágico de lo que alguna vez fue un ALU en FPGA.
dhchdhd
3

Al menos en el componente de división Altera ALT_FP, la división de doble precisión de 64 bits (mantisa de 52 bits) toma 10, 24 o 61 ciclos de reloj (seleccionable). La precisión extendida individual puede variar. Por ejemplo, la división de 43 bits donde el exponente es de 11 bits, la mantisa es de 26 bits, permite seleccionar las opciones de latencia de salida de reloj: 8, 18 o 35. Inicie ISE y verifique lo que puede tener en Xilinx.

Sócrates
fuente
1
¿Son estos números latencia o rendimiento?
Brian Drummond
¿Se pueden seleccionar ciclos de reloj de doble precisión? ¿Por qué factor? ¿Usar más / menos bloques? ¿Y qué hay de la multiplicación?
TheFlash
1
No me he movido junto con los parámetros del componente, solo inicié una ventana principal y copié lo que dice. Probablemente necesite leer el documento y verificar qué otros parámetros ofrece la interfaz gráfica de usuario del componente. Entonces, básicamente, no puedo responder a ambas preguntas por ahora.
Sócrates
2

No hay razón para que no pueda tomar un solo ciclo. Sin embargo, probablemente sería un ciclo bastante grande y usaría muchos recursos ...

Martin Thompson
fuente
1

Tengo implementaciones de doble precisión, multiplicación y división de punto flotante. La multiplicación toma 13 ciclos de reloj y la división toma 109 ciclos de reloj. Ambos están canalizados para un rendimiento del 100% (un resultado por reloj) y una operación de aproximadamente 200MHz en un Xilinx V5. No sé cuántos menos relojes podrías obtener a 100MHz, pero dividir entre dos sería una apuesta segura.

También tengo implementaciones de punto flotante de precisión simple que toman 10 y 51 relojes en la misma situación.

Jim
fuente