9 votos

¿Pueden los procesadores y relojes más rápidos ejecutar más código?

Estoy escribiendo un programa para ejecutarlo en un ATmega 328 que funciona a 16Mhz (es un Arduino Duemilanove si los conoces, es un chip AVR).

Tengo un proceso de interrupción que se ejecuta cada 100 microsegundos. Es imposible, diría yo, calcular cuánto "código" se puede ejecutar en un bucle de 100 microsegundos (estoy escribiendo en C, que presumiblemente se convierte en ensamblador y luego en una imagen binaria).

También dependerá de la complejidad del código (por ejemplo, una línea gigante puede ir más lenta que varias líneas cortas).

¿Es correcto lo que entiendo, en el sentido de que mi procesador con una velocidad de reloj de 16Mhz realiza 16 millones de ciclos por segundo (esto significa 16 ciclos por microsegundo 16.000.000/1.000/1.000); y por lo tanto, si quiero hacer más en mi bucle de 100 microsegundos, la compra de un modelo más rápido como una versión de 72Mhz me daría 72 ciclos por microsegundo (72.000.000/1.000/1.000)?

Actualmente se ejecuta un poco demasiado lento, es decir, su toma un poco más de 100 microsegundos para hacer el bucle (cuánto tiempo exactamente es demasiado difícil de decir, pero poco a poco se queda atrás) y me gustaría que hacer un poco más, es este un enfoque sano conseguir un chip más rápido o me he vuelto loco?

9voto

JW. Puntos 145

En general, el número de instrucciones de ensamblaje que el dispositivo puede ejecutar por segundo dependerá del mezcla de instrucciones y cuántos ciclos necesita cada tipo de instrucción (IPC) para ejecutar. En teoría, podrías contar los ciclos de tu código mirando el archivo asm desensamblado y buscando la función que te preocupa, contando todos los diferentes tipos de instrucciones que contiene, y buscando los ciclos en la hoja de datos de tu procesador.

El problema de determinar el eficaz El número de instrucciones por segundo se agrava en los procesadores más complejos por el hecho de que están canalizados y tienen cachés y demás. Este no es el caso de un dispositivo sencillo como un ATMega328, que es un procesador de una sola instrucción en vuelo.

En cuanto a cuestiones prácticas, para un dispositivo sencillo como un AVR, mi respuesta sería más o menos "sí". Duplicar la velocidad de reloj debería reducir a la mitad el tiempo de ejecución de cualquier función. Para un AVR, sin embargo, no funcionan a más de 20 MHz, por lo que sólo podrías "overclockear" tu Arduino otros 4 MHz.

Este consejo no no generalizar a un procesador con características más avanzadas. Duplicar la velocidad de reloj de tu procesador Intel no duplicará en la práctica el número de instrucciones que ejecuta por segundo (debido a errores de predicción de bifurcaciones, pérdidas de caché, etc.).

8voto

fearphage Puntos 250

@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!

5voto

user4245 Puntos 324

Otra cosa a tener en cuenta - probablemente hay algunas optimizaciones que puede realizar para hacer su código más eficiente.

Por ejemplo - Tengo una rutina que se ejecuta desde dentro de una interrupción del temporizador. La rutina tiene que completarse en 52µS, y tiene que recorrer una gran cantidad de memoria mientras lo hace.

Conseguí un gran aumento de velocidad bloqueando la variable del contador principal en un registro con (en mi µC y compilador - diferente para el tuyo):

register unsigned int pointer asm("W9");

No conozco el formato de tu compilador - RTFM, pero habrá algo que puedas hacer para que tu rutina sea más rápida sin tener que cambiar a ensamblador.

Dicho esto, es probable que tú puedas optimizar tu rutina mucho mejor que el compilador, por lo que cambiar a ensamblador puede suponer un enorme aumento de la velocidad.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X