@vicatcu la respuesta es bastante completa. Una cosa más a tener en cuenta es que la CPU puede ejecutar en los estados de espera (estancado ciclos de CPU) cuando el acceso a e/S, incluyendo el programa y memoria de datos.
Por ejemplo, estamos usando la TI F28335 DSP; algunas áreas de la memoria RAM son 0-estado de espera para el programa y memoria de datos, por lo que al ejecutar el código en la memoria RAM, que se ejecuta en 1 ciclo por instrucción (excepto para aquellos instrucciones que tomar más de 1 ciclo). Cuando se ejecuta el código de la memoria FLASH (integrada en la EEPROM, más o menos), sin embargo, no se puede ejecutar en el total de 150MHz y es varias veces más lento.
Con respecto a la alta velocidad código de interrupción, usted debe aprender una serie de cosas.
En primer lugar, familiarizarse con su compilador. Si el compilador hace un buen trabajo, no debería ser mucho más lento que mano el código de la asamblea para la mayoría de las cosas. (donde "mucho más lento": un factor de 2 estaría bien por mí; un factor de 10, sería inaceptable) Usted necesita aprender cómo (y cuándo) para utilizar el compilador de optimización de banderas, y de vez en cuando, usted debe buscar en el compilador de salida para ver cómo lo hace.
Algunas otras cosas que usted puede tener el compilador hacer para speedup código:
usar funciones inline (no recuerdo si C es compatible con este o si es sólo una C++-ism), tanto para la pequeña y funciones para las funciones que se van a ejecutar sólo una vez o dos veces. El inconveniente es que las funciones en línea son difíciles de depurar, sobre todo si la optimización del compilador está activado. Pero guardar innecesario de llamada/retorno de las secuencias, sobre todo si la "función" de la abstracción para el diseño conceptual fines en lugar de la aplicación del código.
Mira a tu compilador del manual para ver si tiene funciones intrínsecas -- estos son compilador dependiente de funciones integradas que se corresponden directamente con el procesador de instrucciones de montaje; algunos procesadores tienen instrucciones de montaje que hacer cosas útiles, como min / max / bit inversa y usted puede ahorrar tiempo de hacerlo.
Si usted está haciendo computación numérica, asegúrese de que no está llamando a la matemática-funciones de la biblioteca innecesariamente. Tuvimos un caso en el que el código era algo como y = (y+1) % 4
para un contador que tenía un período de 4 a espera de que el compilador para implementar el modulo 4 como un bit a bit-Y. En su lugar se llamó a la librería math. Lo hemos sustituido con y = (y+1) & 3
para hacer lo que quería.
Familiarizarse con los bits con los hacks de la página. Te garantizo que vas a utilizar al menos uno de estos a menudo.
Usted también debe ser el uso de la CPU del temporizador periférico(s) para medir la ejecución de código de tiempo -- la mayoría de ellos tienen un temporizador/contador que se puede configurar para que se ejecute en la frecuencia de reloj del CPU. Captura de una copia de la contestación al principio y al final de su código crítico, y usted puede ver cuánto tiempo tarda. Si usted no puede hacer eso, otra alternativa es bajar un pin de salida en el comienzo de su código, y elevar a la final, y mira esta salida en un osciloscopio a la hora de la ejecución. Hay ventajas y desventajas de cada enfoque: la interna temporizador/contador es más flexible (usted puede tener un tiempo de varias cosas), pero más difícil de sacar la información, mientras que la configuración de/eliminación de un pin de salida es inmediatamente visible en un ámbito y se puede estadísticas de captura, pero es difícil distinguir varios eventos.
Por último, hay una muy importante habilidad que se adquiere con la experiencia-tanto generales como específicas del procesador/compilador combinaciones: saber cuando y cuando no a optimizar. En general la respuesta es que no hay que optimizar. Donald Knuth de la cita se coloca con frecuencia en StackOverflow (por lo general sólo la última parte):
Debemos olvidar los pequeños de la eficiencia, dicen que cerca del 97% del tiempo: optimización prematura es la raíz de todos los males
Pero estás en una situación en la que usted sabe que usted tiene que hacer algún tipo de optimización, así que es hora de morder la bala y optimizar (o conseguir un procesador más rápido, o ambos). ¿ NO escribir todo tu ISR en la asamblea. Que es casi una garantía de un desastre, si lo haces, dentro de meses o incluso semanas te voy a olvidar partes de lo que hizo y por qué, y el código es probable que sea muy frágil y difícil de cambiar. Probablemente hay partes del código, sin embargo, que son buenos candidatos para la asamblea.
Señales de que las partes del código que son adecuados para el montaje de codificación:
- las funciones que están bien contenidos, bien definido pequeñas rutinas poco probable que cambie
- funciones que pueden utilizar las específicas instrucciones de montaje (min/max/derecho shift/etc)
- las funciones que se llama muchas veces (consigue un multiplicador: si guarda 0.5 usec en cada llamada, y que se llama 10 veces, que le ahorra 5 usec que es significativa en su caso)
Aprender el compilador de convenciones de llamada de función (por ejemplo, donde pone los argumentos en los registros, y que los registros de guarda/restaura), de modo que usted puede escribir C-se puede llamar rutinas en ensamblador.
En mi proyecto actual, tenemos una muy grande código fuente con el crítico de código que se ejecuta en un 10kHz interrupción (100usec -- ¿suena familiar?) y no hay que muchas de las funciones que están escritas en la asamblea. Los que son, son cosas como el cálculo del CRC, el software de colas, ADC ganancia/compensación.
Buena suerte!