2008-12-01 31 views
11

Me doy cuenta de que esta pregunta es imposible de responder en forma absoluta, pero solo estoy después de las cifras del estadio:¿Cuántas instrucciones asm por instrucción C?

Dado un programa C de tamaño razonable (miles de líneas de código), en promedio, cuántas instrucciones ASM tendrían ser generado. En otras palabras, ¿qué es una relación de instrucción C-ASM realista? Siéntase libre de hacer suposiciones, como 'con las arquitecturas x86 actuales'.

Intenté Google acerca de esto, pero no pude encontrar nada.

Adición: al darse cuenta de cuánta confusión produjo esta pregunta, siento la necesidad de una explicación: lo que quería saber por esta respuesta, es saber, en términos prácticos, qué significa "3GHz". Soy plenamente consciente de que el rendimiento por Herz varía enormemente según la arquitectura, el hardware, las memorias caché, la velocidad del bus y la posición de la luna.

No estoy buscando una respuesta precisa y científica, sino más bien una respuesta empírica que podría ponerse en escalas insondables.

Esta no es una respuesta trivial al lugar (como me di cuenta), y este fue mi mejor esfuerzo al respecto. Sé que la cantidad de líneas resultantes de ASM por línea de C varía según lo que esté haciendo. i++ no se encuentra en el mismo barrio que sqrt(23.1) - Lo sé. Además, no importa qué ASM obtenga de la C, la ASM se interpreta en varios conjuntos de microcódigos dentro del procesador, lo cual, de nuevo, depende de si está ejecutando AMD, Intel u otra cosa, y sus respectivas generaciones. Soy consciente de esto también.

Las respuestas del estadio que he obtenido hasta ahora son lo que he estado buscando: Un proyecto suficientemente grande promedia aproximadamente 2 líneas de ASM x86 por 1 línea de ANSI-C. Los procesadores de hoy en día promediarían alrededor de un comando de ASM por ciclo de reloj, una vez que se llenen las tuberías y se les dé una muestra lo suficientemente grande.

+0

¿Qué decisión tomaría usted que depende de la respuesta a esta pregunta? – EvilTeach

Respuesta

10

No estoy seguro de lo que entendemos por "C-instrucción", tal declaración o linea? Por supuesto, esto variará mucho debido a una serie de factores, pero después de ver algunos programas de muestra propios, muchos de ellos están cerca de la marca de 2-1 (2 instrucciones de ensamblaje por LOC), no sé qué significa o cómo podría ser útil.

Puede resolver esto usted mismo para cualquier combinación particular de programa e implementación pidiéndole al compilador que genere solo el ensamblado (gcc -S por ejemplo) o usando un desensamblador en un ejecutable ya compilado (pero necesitaría el código fuente para compararlo de todos modos).

Editar

Sólo para ampliar esta base de su aclaración de lo que está tratando de lograr (la comprensión de cómo muchas líneas de código de un procesador moderno pueden ejecutar en un segundo):

Mientras que una El procesador moderno puede funcionar a 3 mil millones de ciclos por segundo, lo que no significa que pueda ejecutar 3 mil millones de instrucciones por segundo. Aquí hay algunas cosas a considerar:

  • Muchas instrucciones tardan varios ciclos en ejecutarse (las operaciones de división o coma flotante pueden llevar docenas de ciclos para ejecutarse).
  • La mayoría de los programas pasan la mayor parte de su tiempo esperando cosas como accesos a memoria, discos, etc.
  • Muchos otros factores, incluidos los gastos generales del sistema (programación, llamadas al sistema, etc.) también son factores limitantes.

Pero en general sí, los procesadores son increíblemente rápidos y pueden lograr cosas increíbles en un corto período de tiempo.

+0

Como dije, estaba pidiendo cifras brutales, y su proporción empírica 2: 1 responde perfectamente mi pregunta. Gracias por su respuesta. –

+0

Tengo que preguntar, ¿qué intentas hacer exactamente? –

+0

Como usted insiste, estoy más o menos tratando de entender bien, en términos prácticos, qué, digamos, 3 GHz de potencia de procesamiento realmente significa. Ahora bien, no importa si se trata de mil millones de instrucciones por segundo o una décima parte de eso, ya que no es más que una carga métrica. –

4

¡Eso varía tremendamente! No le creería a nadie si trataban de ofrecer una conversión aproximada.

Declaraciones como i++; se pueden traducir a una sola INC AX.

Las declaraciones para las llamadas a funciones que contienen muchos parámetros pueden ser docenas de instrucciones, ya que la pila está configurada para la llamada.

Luego agregue allí la optimización del compilador que ensamblará su código de una manera diferente a como lo escribió, eliminando así las instrucciones.

También algunas instrucciones funcionan mejor en los límites de las palabras de la máquina para que NOP s salpiquen a lo largo de su código.

1

No estoy seguro de que realmente haya una respuesta útil para esto. Seguramente tendrá que elegir la arquitectura (como sugirió).

Lo que haría: tomar un programa C de tamaño razonable. Dale a gcc la opción "-S" y mírate. Generará el código fuente del ensamblador y usted mismo podrá calcular la proporción para ese programa.

21

No hay respuesta posible. las declaraciones como int a; pueden requerir cero líneas de asm. mientras que las declaraciones como a = call_is_inlined(); pueden requerir 20 líneas de ASM.

Puede verse compilando un programa c, y luego comenzando objdump -Sd ./a.out.Mostrará los códigos ASM y C entremezclados, para que pueda ver cuántas líneas ASM se generan para una línea C. Ejemplo:

test.c

int get_int(int c); 
int main(void) { 
    int a = 1, b = 2; 
    return getCode(a) + b; 
} 

$ gcc -c -g test.c

$ objdump -Sd ./test.o

00000000 <main>: 
int get_int(int c); 
int main(void) { /* here, the prologue creates the frame for main */ 
    0: 8d 4c 24 04    lea 0x4(%esp),%ecx 
    4: 83 e4 f0    and $0xfffffff0,%esp 
    7: ff 71 fc    pushl -0x4(%ecx) 
    a: 55      push %ebp 
    b: 89 e5     mov %esp,%ebp 
    d: 51      push %ecx 
    e: 83 ec 14    sub $0x14,%esp 
    int a = 1, b = 2; /* setting up space for locals */ 
    11: c7 45 f4 01 00 00 00 movl $0x1,-0xc(%ebp) 
    18: c7 45 f8 02 00 00 00 movl $0x2,-0x8(%ebp) 
    return getCode(a) + b; 
    1f: 8b 45 f4    mov -0xc(%ebp),%eax 
    22: 89 04 24    mov %eax,(%esp) 
    25: e8 fc ff ff ff   call 26 <main+0x26> 
    2a: 03 45 f8    add -0x8(%ebp),%eax 
} /* the epilogue runs, returning to the previous frame */ 
    2d: 83 c4 14    add $0x14,%esp 
    30: 59      pop %ecx 
    31: 5d      pop %ebp 
    32: 8d 61 fc    lea -0x4(%ecx),%esp 
    35: c3      ret 
+0

Gracias por su ejemplo muy vívido. Por desgracia, estaba más interesado en el promedio de un estadio de béisbol, ya que soy consciente de que hay gastos generales en ciertas operaciones. Sin mencionar funciones complejas. Pero, aún así, afirmo que la relación asm: c se estabiliza lo suficiente con el tiempo, con suficientes líneas de código. –

2

Dependiendo de su entorno se puede utilizar la opción de Visual Studio:/AF

más here

3

No creo que se puede concluir nada útil alguno sobre el rendimiento de las aplicaciones reales de lo estás tratando de hacer aquí. A menos que "no sea preciso" significa "dentro de varios órdenes de magnitud".

Está demasiado generalizado, y está descartando el almacenamiento en caché, etc., como si fuera secundario, mientras que puede ser totalmente dominante.

Si su aplicación es lo suficientemente grande como para haber tenido una tendencia a algunas instrucciones-por-loc promedio, entonces también será lo suficientemente grande como para tener E/S o en los temas de acceso a la memoria RAM muy menos significativos a tener en cuenta.

1

RISC o CISC?¿Qué es una instrucción en C, de todos modos?

Lo cual es repetir los puntos anteriores que realmente no tienes idea hasta que te vuelvas muy específico sobre el tipo de código con el que estás trabajando.

Puede tratar de revisar la literatura académica relacionada con la optimización del ensamblaje y la interferencia cruzada de hardware/software que ha sucedido en los últimos 30-40 años. Ahí es donde encontrarás algún tipo de datos reales sobre lo que te interesa. (Aunque te advierto, podrías terminar viendo datos C-> PDP en lugar de datos C-> IA-32).

1

Usted escribió en uno de los comentarios que quiere saber qué significa 3GHz.

Incluso la frecuencia de la CPU no importa. Las PC-CPU modernas intercalan y programan las instrucciones en gran medida, captan y captan previamente, almacenan en caché la memoria y las instrucciones, y con frecuencia esa caché se invalida y se arroja al contenedor. La mejor interpretación de la potencia de procesamiento se puede obtener mediante la ejecución de puntos de referencia del rendimiento en el mundo real.

Cuestiones relacionadas