Programacion Efciente en C Para ARM
Short Description
Download Programacion Efciente en C Para ARM...
Description
Programación eficiente en C para ARM Técnicas Digitales II, UTN-FRBA, Año 2009 Los siguientes conceptos de optimización de código para ARM fueron probados con el compilador propietario del software Keil Uvision3, Toolchain: Realview MDKARM Versión:3.80a. 1º) Local Data Types – Tipos de Variables locales: •
Siempre es conveniente trabajar con variables tipo int o long (ambos son de 32bits).
Justificación: Existen instrucciones para el movimiento de datos de 8, 16 y 32bits. Sin embargo, los registros son de 32 bits y las operaciones se efectúan en 32 bits. Esto genera programas más largos. Ejemplos: a) c2=c1+c2;
/*Operaciones con char*/
Por cada operación entre chars, se debe hacer una máscara para alojarlo en un registro de 32bits. b) s2=s1+s2;
/*Operaciones con short*/
La operación entre short, es signada y debe trasladar bit 15 de signo hasta el bit 31 del registro de 32bits. Para operaciones de short sin signo, hace una máscara similar a como lo hace con los char. c) i2=i1+i2; ui2=ui1+ui2;
/*Operaciones con int*/ /*Operaciones con unsigned int*/
La operación más simple entre registros de 32 bits. 2º) Function Argument Types – Variables pasadas como argumentos de funciones: •
Siempre es conveniente pasar argumentos y devolver resultados con variables tipo int o long (ambos son de 32bits).
Programación eficiente en C para ARM Técnicas Digitales II, UTN-FRBA, Año 2009 Justificación: Cualquier tipo de argumento se pasa a través de alguno de los registros de 32bits. Será tarea del compilador agregar instrucciones de más para manejar los argumentos como corresponde y entregar los resultados conforme al tipo de dato de salida. Esto genera programas más largos. *o todos los compiladores tienen el mismo comportamiento. Ejemplos: a) /*Función suma char*/ int suma_char(char c3, char c4) {c3=c3+c4; return (c3);} /*Llamado a la función*/ c1=suma_char(c1,c2);
Los argumentos se pasan en R0 y R1, como valores de 32bits. El retorno se hace a través de R0, pero truncado a tipo char. b) /*Función suma short*/ short suma_short(short s3, short s4) {s3=s3+s4; return(s3);} /*Llamado a la función*/ s1=suma_short(s1,s2);
Los argumentos se pasan en R0 y R1, como valores de 32bits. El retorno se hace a través de R0, pero truncado a tipo short. 3º) Signed versus Unsigned Types – Variables signadas o no signada: •
Siempre es conveniente emplear variables no signadas cuando se realicen operaciones matemáticas complejas que incluyan, además, divisiones.
Justificación:
Programación eficiente en C para ARM Técnicas Digitales II, UTN-FRBA, Año 2009 Si bien las divisiones y multiplicaciones por 2 se logran con un desplazamiento, no es válida esta estrategia cuando son variables signadas. Por otro lado, las familias ARM7 no incluyen el hardware para realizar divisiones, por lo tanto, se realiza por soft. Una división con signo deberá recurrir a una rutina de mayor código y tardará más. Ejemplos: a) ui1=ui1/4;
/*División sin signo por Barrel Shifter*/
i1=i1/4; /*División con signo por Barrel Shifter*/
Se genera un código más extenso en la división por potencias de 2 cuando se trabaja con variables signadas. a) ui1=ui1/ui2;
/*División sin signo*/
i1=i1/i2;
/*División con signo*/
Se ejecutan por software a través de dos rutinas diferentes: Symbol Size __aeabi_idivmod 0x00000214 ARM Code 384 __aeabi_uidivmod 0x00000600 ARM Code 28 El tiempo de ejecución para la rutina sin signo es del 85% de la rutina con signo. 4º) C looping structures – Bucles: • •
Siempre emplear variables de control del bucle en forma descendente e independiente, que finalicen el bucle cuando se hacen cero. Para bucles que tienen como mínimo un ciclo, emplear do - while en vez de for.
Programación eficiente en C para ARM Técnicas Digitales II, UTN-FRBA, Año 2009 •
Agrupar ciclos, en un ciclo más extenso, pero que no rompe el Pipeline.
Justificación: Existe el ya conocido flag de Zero que evita todo tipo de comparación a la hora de finalizar un bucle. Cuando se emplean bucles for, se generan más líneas de código al inicio del bucle, que al ser un bucle de más de un ciclo, son innecesarias y extienden el tiempo total del bucle. Cualquier tipo de salto en una arquitectura ARM rompe el Pipeline, es decir, la próxima instrucción no se ejecutará hasta no llegar a la etapa de ejecución del Pipeline. Por lo tanto, por cada ciclo (salto al inicio) se estarán perdiendo ciclos donde el micro no ejecuta ninguna instrucción, sino que se prepara para ejecutarla. IMPORTANTE: Estas optimizaciones se lograron al configurar al compilador en nivel de optimización -02. Ejemplos: a) for (i=0;i
View more...
Comments