¿Las excepciones siguen siendo indeseables en el entorno en tiempo real?


Hace un par de años me enseñaron que en las aplicaciones en tiempo real tales como Sistemas Embebidos o (No-Linux -) Kernel-development C++-Exceptions son indeseables. (Tal vez esa lección fue de antes de gcc-2.95). Pero también sé que el manejo de excepciones ha mejorado.

Por lo tanto, son C++-Excepciones en el contexto de aplicaciones en tiempo real {[4] } en la práctica

  • ¿totalmente indeseado?
  • incluso para ser apagado vía vía compilador-switch?
  • o muy cuidadosamente utilizable?
  • o manejados tan bien ahora, que uno puede usarlos casi libremente, con un par de cosas en mente?
  • ¿C++11 cambia algo w.r.t. esto?

Actualización : El manejo de excepciones realmente requiere RTTI que se habilite (como sugirió un respondedor)? ¿Hay moldes dinámicos involucrados, o similares?

Author: sashoalm, 2011-03-10

8 answers

Las excepciones ahora están bien manejadas, y las estrategias utilizadas para implementarlas las hacen de hecho más rápidas que probar el código de retorno, porque su costo (en términos de velocidad) es virtualmente nulo, siempre y cuando no arroje ninguna.

Sin embargo cuestan: en tamaño de código. Las excepciones generalmente funcionan de la mano con RTTI, y desafortunadamente RTTI es diferente a cualquier otra característica de C++, ya que se activa o desactiva para todo el proyecto, y una vez activado generará código suplementario para cualquier clase que tenga un método virtual, desafiando así la mentalidad de "no pagas por lo que no usas".

Además, requiere código suplementario para su manejo.

Por lo tanto, el costo de las excepciones debe medirse no en términos de velocidad, sino en términos de crecimiento de código.

EDIT :

De @Space_C0wb0y: Este artículo de blog da una pequeña visión general, e introduce dos métodos generalizados para implementar excepciones Saltos y Coste cero. Como su nombre indica, los buenos compiladores ahora usan el mecanismo de Costo cero.

El artículo de Wikipedia sobre el Manejo de Excepciones habla sobre los dos mecanismos utilizados. El mecanismo de costo cero es el basado en tablas.

EDIT :

De @Vlad Lazarenko cuyo blog mencioné anteriormente, la presencia de excepciones lanzadas podría evitar que un compilador incruste y optimice el código en los registros.

 22
Author: Matthieu M.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-03-11 19:09:50

Responde solo a la actualización:

El manejo de excepciones realmente requiere RTTI habilitada

El manejo de excepciones en realidad requiere algo más poderoso que RTTI y dynamic cast en un aspecto. Considere el siguiente código:

try {
    some_function_in_another_TU();
} catch (const int &i) {
} catch (const std::logic_error &e) {}

Entonces, cuando la función en la otra TU se lanza, va a buscar la pila (ya sea verificar todos los niveles inmediatamente, o verificar un nivel a la vez durante el desenrollado de la pila, eso depende de la implementación) para una captura cláusula que coincide con el objeto que se lanza.

Para realizar esta coincidencia, es posible que no necesite el aspecto de RTTI que almacena el tipo en cada objeto, ya que el tipo de una excepción lanzada es el tipo estático de la expresión lanzada. Pero necesita comparar tipos de una manera instanceof, y necesita hacer esto en tiempo de ejecución, porque some_function_in_another_TU se puede llamar desde cualquier lugar, con cualquier tipo de captura en la pila. A diferencia de dynamic_cast, necesita realizar esta instancia de tiempo de ejecución en tipos que tienen no hay funciones miembro virtuales, y para eso importan los tipos que no son tipos de clase. Esa última parte no agrega dificultad, porque los tipos que no son de clase no tienen jerarquía, por lo que todo lo que se necesita es igualdad de tipo, pero aún necesita identificadores de tipo que se puedan comparar en tiempo de ejecución.

Por lo tanto, si habilita excepciones, entonces necesita la parte de RTTI que hace comparaciones de tipos, como las comparaciones de tipos de dynamic_cast pero que cubren más tipos. No necesita necesariamente la parte de RTTI que almacena los datos se utiliza para realizar esta comparación en la vtable de cada clase, donde es accesible desde el objeto the los datos solo podrían codificarse en el punto de cada expresión throw y cada cláusula catch. Pero dudo que sea un ahorro significativo, ya que los objetos typeid no son exactamente masivos, contienen un nombre que a menudo se necesita de todos modos en una tabla de símbolos, además de algunos datos definidos por la implementación para describir la jerarquía de tipos. Así que probablemente también podría tener todo RTTI en ese punto.

 11
Author: Steve Jessop,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-03-10 18:53:36

El problema con las excepciones no es necesariamente la velocidad (que puede diferir mucho, dependiendo de la implementación), pero es lo que realmente hacen.

En el mundo en tiempo real, cuando tiene una restricción de tiempo en una operación, necesita saber exactamente qué hace su código. Las excepciones proporcionan atajos que pueden influir en el tiempo de ejecución general del código (el controlador de excepciones puede no encajar en la restricción en tiempo real o, debido a una excepción, puede que no devuelva la respuesta de la consulta en todos, por ejemplo).

Si se refiere a "tiempo real" como de hecho "incrustado", entonces el tamaño del código, como se mencionó, se convierte en un problema. El código incrustado puede no ser necesariamente en tiempo real, pero puede tener restricciones de tamaño (y a menudo lo hace).

Además, los sistemas embebidos a menudo están diseñados para ejecutarse para siempre, en un bucle de eventos infinito. Excepción puede llevarlo a algún lugar fuera de ese bucle, y también corromper la memoria y los datos (debido a la pila de desenrollado) - de nuevo, depende de lo que haga con ellos, y cómo el compilador realmente lo implementa.

Así que mejor prevenir que lamentar: no use excepciones. Si puede soportar fallas ocasionales del sistema, si se está ejecutando en una tarea separada que se puede reiniciar fácilmente, si no está realmente en tiempo real, solo finja que lo está, entonces probablemente pueda intentarlo. Si usted está escribiendo software para un corazón-pacer - preferiría comprobar códigos de vuelta.

 8
Author: littleadv,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-03-10 09:03:19

Las excepciones de C++ todavía no son compatibles con todos los entornos en tiempo real de una manera que las hace aceptables en todas partes.

En el ejemplo particular de los videojuegos (que tienen una fecha límite suave de 16.6 ms para cada fotograma), los compiladores líderes implementan excepciones de C++ de tal manera que simplemente activar el manejo de excepciones en su programa lo ralentizará significativamente y aumentará el tamaño del código, independientemente de si realmente lanza excepciones o no. Teniendo en cuenta que tanto el rendimiento y la memoria es crítica en una consola de juegos, eso es un problema: las unidades SPU de PS3, por ejemplo, tienen 256 kb de memoria tanto para código como para datos.

Además de esto, lanzar excepciones sigue siendo bastante lento (mídalo si no me crees) y puede causar desasignaciones de montón que también son indeseables en casos en los que no tienes microsegundos de sobra.

El uno... er... excepción Que he visto a esta regla son los casos en los que la excepción podría ser lanzada una vez por ejecución de aplicación -- no una vez por fotograma, sino literalmente una vez. En ese caso, el manejo estructurado de excepciones es una forma aceptable de capturar datos de estabilidad del sistema operativo cuando un juego se bloquea y transmitirlos al desarrollador.

 5
Author: Crashworks,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-03-10 09:04:48

La implementación del mecanismo de excepción suele ser muy lenta cuando se lanza una excepción, de lo contrario los costos de su uso son casi nulos. En mi opinión, las excepciones son muy útiles si las usas correctamente.

En las aplicaciones RT, las excepciones deben lanzarse solo cuando algo sale mal y el programa tiene que detenerse y solucionar el problema (y posiblemente esperar la interacción del usuario). En tales circunstancias, se necesita más tiempo para solucionar el problema.

Las excepciones proporcionan ocultos ruta de notificación de un error. Hacen que el código sea más corto y más legible, por lo tanto, un mantenimiento más fácil.

 3
Author: BЈовић,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-03-10 08:56:20

Las implementaciones típicas del manejo de excepciones en C++ aún no eran ideales, y podrían causar que toda la implementación del lenguaje fuera casi inutilizable para algunos destinos incrustados con recursos extremadamente limitados, incluso si el código de usuario no usa explícitamente estas características. Esto se conoce como" violación del principio de sobrecarga cero " por documentos recientes del WG21, ver N4049 y N4234 para más detalles. En tales entornos, el manejo de excepciones no funciona como se espera (consumiendo un sistema razonable recursos) si la aplicación es en tiempo real o no.

Sin embargo, debe haber aplicaciones en tiempo real en entornos embebidos que puedan permitirse estos gastos generales, por ejemplo, un reproductor de video en un dispositivo portátil.

El manejo de excepciones siempre debe usarse con cuidado. Lanzar y capturar excepciones por fotograma en una aplicación en tiempo real para cualquier plataforma (no solo para entornos embebidos) es un mal diseño/implementación y no es aceptable en general.

 1
Author: FrankHB,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-11-20 13:28:20

Hay un inconveniente de excepciones más.

Las excepciones generalmente se manejan bien y fácilmente en lenguajes con administración automática de memoria (como C#, python, etc.)

Pero en C++, donde la mayoría de las veces uno tiene que controlar la asignación de memoria y la desasignación de objetos (new y delete), en muchas situaciones las excepciones se volvieron muy complicadas. Cuando la excepción ocurre a menudo uno necesita liberar los recursos asignados antes. Y en algunos casos es difícil elegir un momento adecuado y un lugar para ello. Y cosas como los punteros automáticos podrían salvarte solo en algunos casos.

Las fugas de memoria, los valores de segmento o el comportamiento imprevisto pueden ser el resultado de un manejo inadecuado de objetos/memoria durante las excepciones que se lanzan en C++. Esto conduce a un desarrollo más lento y a la depuración de errores realmente complicados.

 -1
Author: MajesticRa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-03-10 10:17:11

Generalmente hay 3 o 4 restricciones en el desarrollo embebido / en tiempo real, especialmente cuando eso implica el desarrollo en modo kernel

  • En varios puntos, generalmente mientras se manejan excepciones de hardware, LAS operaciones NO DEBEN generar más excepciones de hardware. las estructuras de datos implícitas de c++(vtables) y el código (constructores y operadores predeterminados y otro código generado implícitamente para soportar el mecanisim de excepción de c++) no se pueden colocar, y como resultado no se puede garantizar que sean se coloca en memoria no paginada cuando se ejecuta en este contexto.

  • Calidad del código: el código c++ en general puede ocultar mucha complejidad en sentencias que parecen triviales, lo que dificulta la auditoría visual del código en busca de errores. las excepciones desacoplan el manejo de la ubicación, lo que dificulta la comprobación de la cobertura del código de las pruebas.

  • C++ expone un modelo de memoria muy simple: new asigna desde una tienda gratuita infinita, hasta que se agota, y lanza una excepción. En la memoria limitada dispositivos, se puede escribir código más eficiente que hace uso explícito de bloques de memoria de tamaño fijo. Las asignaciones implícitas de C + en casi cualquier operación hacen imposible auditar el uso de la memoria. Además, la mayoría de los montones de c++ exhiben la inquietante propiedad de que no hay un límite superior computable sobre el tiempo que puede tomar una asignación de memoria, lo que nuevamente hace difícil probar el tiempo de respuesta de los algoritmos en dispositivos en tiempo real donde los límites superiores fijos son deseables.

 -1
Author: Chris Becke,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-03-10 10:36:20