jueves, 31 de octubre de 2013

Unidad en punto flotante (FPU) Cortex M4

Cuando programamos cualquier algoritmo para un PC, ya sea en C, C++, VB.NET, Pascal... o cualquier otro lenguaje, no nos preocupamos de la cantidad o el tipo de datos que utilizamos, normalmente reina en nuestro subconsciente el, Más vale que sobre que no que falte. Esta metodología de programación es completamente válida, a no ser que estemos desarrollando programas en los que la velocidad de ejecución es crítica, y además estemos utilizando sistemas en tiempo real. Los potentes procesadores de PC procesan casi a la misma velocidad un dato del tipo entero, que uno en coma fija, o uno en coma flotante, o en caso de no hacerlo, como he dicho, no es demasiado relevante.
En cambio, si el procesador es mucho más limitado, tanto en velocidad, como en memoria, la cosa cambia drásticamente. Este tipo de limitaciones, las sufrimos, y mucho cuando programamos un microcontrolador, ya sea un PIC, o un potente ARM.
En general, los microcontroladores se desenvuelven muy bien si en nuestros programas introducimos operaciones con números enteros, y mejor si estos números tienen un tamaño igual o menor a la cantidad de bits que dispone en la unidad aritmético-lógica. En cambio, si necesitamos hacer operaciones con números no enteros, la cosa cambia, haciendo que para cualquier operación, el microcontrolador tenga que ejecutar varias decenas de instrucciones. Para este problema, existen 2 soluciones. La primera de ellas es trabajar en un formato de coma fija, o formato IQ, el cual se basa en codificar los números decimales, de forma que para el procesador son números enteros, y de esta forma operar con ellos más rápido. Trabajar con el formato IQ conlleva que para realizar una multiplicación, no podemos utilizar directamente el simbolo *, sino que tenemos que llamar a una función que, después de realizar la multiplicación, vuelva a codificar el número  adecuadamente. La otra opción es olvidarnos de cualquier tipo de codificación y  trabajar  directamente con variables del tipo float, lo cual hace nuestro programa mucho más lento... a no ser que el procesador cuente con una ALU especial  para este tipo de operaciones conocida  como FPU, o Floating Point Unit.
Esta unidad se encarga exclusivamente de operaciones en coma flotante, pudiendo realizar operaciones entre números float realmente rápido. Lo malo, es que esta unidad no se encuentra en la mayoría de los microcontroladores, de hecho, no conozco ningún PIC que la incorpore, y si  nos vamos a DSP de texas, tenemos que coger al menos un TMS320F28335, un DSP de gama alta, para encontrarlo. En cuanto a los ARM, la mayoría de los Cortex M4 si que disponen de una FPU, tanto la Tiva Launchpad de TI, como la STM32F4Discovery.
En esta entrada os voy a explicar como habilitar la FPU en la STM32F4Discovery, y en el vídeo podréis ver una comparativa entre la velocidad de una multiplicación en coma flotante con, y sin FPU. Para poder utilizar la FPU en el STM32F4 se debe introducir un fragmento de código en el archivo system_stm32f4xx.c, dentro de la función SystemInit(). El código es el siguiente:
// Código añadido para habilitar la FPU en el procesador

#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)

    SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2));  /* set CP10 and CP11 Full Access */

  #endif

Con este código le decimos al compilador que dispone de FPU, y luego en la configuración del proyecto, debemos decirle que la utilice.


A continuación os pongo un vídeo con la comparativa.



Espero os resulte interesante!!

No hay comentarios:

Publicar un comentario