studio programacion para móviles libro edición desarrollo desarrollar curso aprende aplicaciones c++ c language-lawyer compiler-optimization

programacion - ¿C/C++ ofrece alguna garantía en tiempo de ejecución mínimo?



manual de programacion android pdf (4)

No especificó el compilador, pero supongamos que es gcc .

gcc no elimina los bucles vacíos, al menos no de acuerdo con la documentation . Contiene el siguiente texto:

Históricamente, GCC no ha eliminado bucles "vacíos" bajo la suposición de que la razón más probable por la que pondría uno en un programa es tener un retraso, por lo que eliminarlos no hará que los programas reales se ejecuten más rápido.

Sin embargo, puede eliminar bucles vacíos si el optimizador los "vacía", es decir, si el bucle contiene código que el optimizador puede mover fuera del bucle, y el bucle resultante está vacío.

No está claro en la documentación si esto sigue siendo cierto en la versión más reciente. El manual menciona "históricamente" sin especificar por qué. Si actualiza su pregunta con información sobre su plataforma y compilador exactos, tal vez se pueda dar una mejor respuesta.

¿Por qué los compiladores parecen ser educados hacia los bucles que no hacen nada y no los eliminan?

¿El estándar C requiere ciclos para tomar algo de tiempo?

Ejemplo, el siguiente código:

void foo(void) { while(1) { for(int k = 0; k < 1000000000; ++k); printf("Foo/n"); } }

funciona más lento que este:

void foo(void) { while(1) { for(int k = 0; k < 1000; ++k); printf("Foo/n"); } }

incluso con el nivel de optimización -O3 . Esperaría eliminar los bucles vacíos permitidos y así obtener la misma velocidad en ambos códigos.

¿El "tiempo pasado" es un efecto secundario que debería ser preservado por un compilador?


No hay un tiempo de ejecución mínimo para un ejecutable C o C ++ porque el tiempo de ejecución depende de muchos problemas específicos de la plataforma, como:

  1. Velocidad de reloj del procesador.
  2. Ciclos de reloj por instrucción.
  3. Optimizaciones de ejecución del procesador interno.
  4. Interrupciones
  5. Conjunto / capacidades de instrucción del procesador.

Algunos procesadores admiten la multiplicación, otros no. Los procesadores que no son compatibles con la multiplicación tardarían más en ejecutar un programa que en un proceso que tiene instrucciones de multiplicación. Lo mismo con punto flotante.

La velocidad de operación interna de un procesador varía. Hay una unidad común de medida del tiempo llamada "ciclo de reloj". La mayoría de los proveedores de procesadores especifican la duración de una instrucción en ciclos de reloj. Esta medición puede ser difícil debido al soporte interno, como la gestión de caché.

Algunos procesadores tienen una lógica que puede optimizar la ejecución de instrucciones o patrones de instrucción. Una optimización es la predicción de bifurcación .

Muchas plataformas tienen interrupciones. Por ejemplo, puede haber una interrupción de "marca de sistema" que permite que el sistema operativo sepa cuándo cambiar la ejecución a otro programa. Algunos no son tan periódicos, como cuando se produce E / S. No se puede garantizar un tiempo de ejecución mínimo cuando se interrumpe el programa.

Establecer un tiempo mínimo de ejecución sería un caos con la portabilidad del lenguaje C y C ++. Algunas plataformas querrían ejecutar código más rápido que el tiempo mínimo. Es posible que otras plataformas no puedan lograr un tiempo de ejecución mínimo (pero podrían beneficiarse de un lenguaje de alto nivel como C).

Además, ¿cómo se mediría el tiempo?

¿Se aplica el tiempo de ejecución mínimo para bucles de retardo o sondeo?


No, el tiempo pasado no cuenta como comportamiento observable para ser protegido por la regla de si-si:

[C++14: 1.8/5]: una implementación conforme que ejecute un programa bien formado debe producir el mismo comportamiento observable que una de las posibles ejecuciones de la instancia correspondiente de la máquina abstracta con el mismo programa y la misma entrada. Sin embargo, si dicha ejecución contiene una operación no definida, esta Norma Internacional no exige que la implementación ejecute ese programa con esa entrada (ni siquiera con respecto a las operaciones que preceden a la primera operación no definida).

[C++14: 1.5/8]: requisitos mínimos en una implementación conforme son:

  • El acceso a los objetos volátiles se evalúa estrictamente de acuerdo con las reglas de la máquina abstracta.
  • Al finalizar el programa, todos los datos escritos en los archivos serán idénticos a uno de los resultados posibles que la ejecución del programa de acuerdo con la semántica abstracta habría producido.
  • La dinámica de entrada y salida de los dispositivos interactivos se llevará a cabo de tal manera que la salida de solicitud se entregue realmente antes de que un programa espere la entrada. Lo que constituye un dispositivo interactivo está definido por la implementación.

Estos colectivamente se conocen como el comportamiento observable del programa. [Nota: cada implementación puede definir correspondencias más estrictas entre la semántica abstracta y la real. -Finalizar nota]

Esos bucles pueden optimizarse legalmente y, de hecho, hay escenarios en los que el estándar hace intentos deliberados para que hacerlo sea aún más fácil:

[C++14: 1.10/24]: la implementación puede suponer que eventualmente cualquier subproceso hará una de las siguientes acciones:

  • Terminar,
  • hacer una llamada a una función de E / S de la biblioteca,
  • acceder o modificar un objeto volátil, o
  • realizar una operación de sincronización o una operación atómica.

[Nota: Esto está diseñado para permitir las transformaciones del compilador, como la eliminación de bucles vacíos, incluso cuando la terminación no pueda ser probada. -Finalizar nota]

De hecho, su compilador puede ser "cortés" al darse cuenta de que la intención del ciclo en estos programas parece ser la ralentización de la emisión de texto repetido. :)


No, no hay garantía: (presupuesto de N1570, 5.1.2.3 Ejecución del programa )

1 Las descripciones semánticas en este estándar internacional describen el comportamiento de una máquina abstracta en la que los problemas de optimización son irrelevantes.

De todos modos, el estándar C solo especifica el comportamiento de su programa cuando se ejecuta en una máquina abstracta, que puede tener memoria infinita y / o CPU.