2010-07-29 28 views
18

Tengo un programa C++ nativo que se ejecuta> 20 veces más lento cuando se inicia con Debug (F5) pero se ejecuta a velocidad normal cuando se usa inicio sin depurar (Ctrl + F5).Aplicación de Visual Studio extremadamente lenta con depuración

No importa si utilizo una versión de depuración o liberación. Además, si uso Windbg, el programa es una magnitud más lenta.

¿Hay alguna configuración que haya elegido mal o algo?

+0

Depurar agrega muchos sobrecargas a un programa. ¿Por qué estás asumiendo que las cosas están mal? – Oded

+0

Debug no debería agregar muchos sobrecargas. La diferencia entre un depurador conectado y no conectado no debería ser una diferencia en absoluto. – plaisthos

Respuesta

14

Establecer la variable de entorno _NO_DEBUG_HEAP a 1 (como se ve en http://preshing.com/20110717/the-windows-heap-is-slow-when-launched-from-the-debugger)

Esto puede hacerse desde dentro de Visual, también.

Ahora esto es solo una solución, tengo curiosidad por saber cómo refactorizar un programa que sufre este tipo de problema. ¿Tiene muchos std :: map's, shared_ptr, o cualquier otra indirección grande por casualidad?

+0

No puedo confirmar si este es realmente el caso en mi programa, pero realmente me parece que es mi problema. – plaisthos

0

Depuración Visual C++ viene con muchos y muchos gastos generales, especialmente en el STL. Intente no definir _DEBUG, y defina NDEBUG.

+2

Sin embargo, eso no responde a la pregunta del OP: sigue siendo una compilación de depuración que acaba de ejecutarse fuera del IDE. El diagnóstico STL seguirá funcionando. –

1

Hay varias cosas que son diferentes si ejecuta la compilación de depuración fuera del IDE. Una es que el IDE tarda un tiempo en cargar símbolos, y si depende de muchas bibliotecas, entonces ese tiempo de inicio puede ser significativo. Si está utilizando un servidor de símbolos (incluido el servidor de símbolos público de Microsoft), esto puede aumentar el tiempo de inicio, así que asegúrese de tener un caché de símbolos local en su variable _NT_SYMBOL_PATH si ese es el caso.

También el IDE se ejecuta con el montón de depuración habilitado, pero no creo que esto ocurra si se ejecuta fuera del IDE.

+0

Estoy usando el servidor de símbolos. Pero no estoy hablando del tiempo de inicio, sino del tiempo que el programa usa para ejecutarse realmente. Tengo un diagnóstico sobre std :: cout, que tiene aproximadamente uno por segundo con Ctrl + F5 y uno de aproximadamente 30 segundos cuando se ejecuta con F5. Creo que la depuración del montón depende de la macro _DEBUG que hará la comprobación del montón en ambos casos. – plaisthos

+0

¿Tiene algún punto de interrupción o punto de referencia condicional establecido? Estos pueden ralentizar la ejecución en un orden de magnitud. Intenta deshabilitar todos los puntos de interrupción temporalmente. –

+0

Desafortunadamente no tengo ninguno. Hubiera sido demasiado fácil :) – plaisthos

12

Esto, por supuesto, no es causado por tener el símbolo _DEBUG definido o compilar el código en la configuración de depuración. El código de depuración agregado se ejecuta ya sea que el depurador esté o no asociado al programa.

El depurador normalmente no afecta a la ejecución del código, se mantiene fuera del camino llamando a WaitForDebugEvent. Lo bloquea, hasta que el sistema operativo le dice que sucedió algo digno de mención. Eso puede desencadenar un montón de código en el depurador que puede ralentizar su programa. Puede ver los eventos enumerados en la documentación de la estructura DEBUG_EVENT.

ellos Anotando un poco más allá de la documentación: los pasos del depurador en y puede ralentizar el programa cuando:

  • El programa se carga o descarga un archivo DLL. Se producen muchas cosas durante la carga, el depurador busca un archivo de símbolos de depuración (.pdb). Puede ponerse en contacto con un servidor de símbolos para descargarlo. Cualquier punto de interrupción que se estableció en el código fuente DLL se activará. Esto puede ser bastante lento, pero el efecto es temporal y generalmente solo ralentiza el inicio. Puede ver la notificación de carga/descarga en la ventana Salida.

  • El programa hace una excepción. Esto activa el depurador en el momento en que se genera la excepción, una "notificación de primera oportunidad". Lo cual puede ser muy útil, puede utilizar la casilla Depurar + Excepción, lanzada para hacer que el depurador se detenga cuando se produce la excepción. Puede ver el mensaje de notificación en la ventana de Salida. Este hace ralentiza el código que aumenta y capta las excepciones tremendamente y es muy probable que sea la fuente de su ralentización. Nunca use excepciones para el control de flujo.

  • Un hilo comienza a ejecutarse o termina. Nuevamente, se imprime un mensaje de notificación en la ventana de Salida. Tendría que crear un lote de subprocesos para hacer esto ralentizar su programa.

  • Cuando su programa usa OutputDebugString() para fines de rastreo. Visible en la ventana de Salida. Otro buen candidato para una desaceleración, la producción cae en el cubo de bits si no hay un depurador conectado.No debe tener problemas para diagnosticar esto como la causa, el efecto secundario obvio es ver un lote de mensajes en la ventana de resultados.

  • Cuando el programa llega a un punto de interrupción. No hay muchas razones para quedar perplejo con eso. Pero puede establecer puntos de interrupción que ralenticen mucho el programa pero que no provoquen un corte en el depurador. En particular, el punto de interrupción condicional, el contador de visitas, el filtro y la operación de cuando se acierta serán lentos. Use Debug + Windows + Breakpoints para revisar los puntos de interrupción definidos.

+0

Usando Prism aquí, entonces cargue muchos módulos después de la puesta en marcha. Parece ser la causa, sí. –

0

Nadie ha mencionado el cierre de ventanas de origen no utilizadas.

Después de cerrar 20+ ventanas sin usar, el paso de la fuente de depuración pasó de ~ 5s a ~ .2s. Este proyecto inusualmente lento carga dinámicamente una DLL y esa DLL también fue la que se abrió paso (y tiene ventanas de origen abiertas) por lo que parece estar relacionada. Sin embargo, esto fue C# (el titular y las etiquetas no son específicas).

+0

yeah velocidad de avance (velocidad ide) es algo completamente diferente que ejecutar una aplicación – plaisthos

+0

Veo, cierto eso, espero que ayude a alguien que fue llevado aquí. – crokusek

0

Cuando se crea un proceso en el depurador, el sistema operativo utiliza de forma predeterminada el montón de depuración. El montón de depuraciones hace más verificación de su memoria, especialmente en des-alloc.

Hay varias opciones posibles con el fin de desactivar el uso del montón de depuración:

  1. asociar al proceso poco después del inicio. Esto le permitirá acelerar el rendimiento en modo de depuración a sabiendas y ser plenamente consciente del modo en el que se está ejecutando.

  2. Agregue la configuración de la variable de entorno _NO_DEBUG_HEAP = 1.
    Esto puede establecerse globalmente para la máquina o para una instancia específica de Visual Studio.

    a. Globalmente, establecería una variable de entorno a través del Panel de control → Sistema → Configuración avanzada del sistema → Variables de entorno, y allí agregaría la variable _NO_DEBUG_HEAP = 1.
    Nota: Esto tendrá un efecto en CADA aplicación que depure.

    b. Para una instancia de Visual Studio puede abrir un símbolo del sistema, establecer la variable de entorno _NO_DEBUG_HEAP = 1 y luego abrir Visual Studio desde el interior del símbolo del sistema. Esto influirá solo en los procesos creados a partir del que la instancia de Visual Studio heredará la variable de entorno .

  3. Anexa el comportamiento del depurador, esto es posible para VS2015. Hay 2 formas de anular esto:

    a.Para modificar para un proyecto específico, vaya a Propiedades del proyecto Propiedades de configuración → Depuración y cambie la propiedad del entorno _NO_DEBUG_HEAP a 1

    b. Para modificar para cada proyecto en Visual Studio, vaya a Herramientas → Opciones → Depuración y marque la opción: "Habilitar el asignador de montón de depuración de Windows (solo nativo)".
    Nota: si la variable de entorno _NO_DEBUG_HEAP mencionada en la 'a' se establece en un nivel de proyecto, anulará esta configuración global.

1

Para mí, la diferencia de rendimiento entre el modo de depuración y liberar modo se trata de un factor . Después de algunas excavaciones, parece que varias cosas contribuyen a la diferencia en el rendimiento, pero hay una opción de compilación que cuadruplica mi rendimiento de depuración casi de forma gratuita.

Es decir, cambiando /ZI en /Zi. Para una descripción, vea de msdn page.

No utilizo la característica editar y continuar de todos modos.

Cuestiones relacionadas