2010-06-02 12 views
5

Tengo un programa que quiero perfilar con gprof. El problema (aparentemente) es que usa enchufes. Por lo que obtener cosas como esta:Uso de gprof con conectores

::select(): Interrupted system call 

llegué a este problema hace un tiempo, se rindió, y siguió adelante. Pero me gustaría poder crear un perfil de mi código, usando gprof si es posible. ¿Que puedo hacer? ¿Hay una opción de gprof que me falta? Una opción de socket? ¿Es gprof totalmente inútil en presencia de este tipo de llamadas al sistema? Si es así, ¿hay una alternativa viable?

EDIT: Plataforma:

  • Linux 2.6 (x64)
  • GCC 4.4.1
  • gprof 2,19
+0

creo que también se debe mencionar su plataforma: sistema operativo, compilador, versión gprof etc. –

+2

me encontré con este artículo: tal vez sea de alguna utilidad: http://unix.derkeiler.com/Newsgroups/comp.unix .programmer/2004-03/0938.html – LoudNPossiblyWrong

+0

¿Ha intentado usar valgrind/kcachegrind en el perfil? Lo prefiero a gprof. –

Respuesta

5

El código del conector necesita para manejar sistema de llamadas interrumpidas independientemente del generador de perfiles, pero en Profiler es inevitable. Esto significa tener un código como.

if (errno == EINTR) { ... 

después de cada llamada al sistema.

Eche un vistazo, por ejemplo, here para el fondo.

+0

Genial, gracias. Seguimiento: http://stackoverflow.com/questions/2958114/handling-eintr-with-goto –

1

gprof (here's the paper) es fiable, pero only was ever intended to measure changes, e incluso para eso, sólo mide los problemas vinculados a la CPU. Nunca se anunció que fuera útil para localizar problemas. Esa es una idea que otras personas colocan encima.

Considere this method.

Otra buena opción, si no te importa gastar algo de dinero, es Zoom.

Agregado: Si puedo darle un ejemplo. Supongamos que tiene una jerarquía de llamadas donde Main llama a A varias veces, A llama B varias veces, B llama a C algunas veces, y C espera algunas E/S con un socket o archivo, y eso es básicamente todo el programa lo hace. Ahora, supongamos además que la cantidad de veces que cada rutina llama al siguiente es un 25% más de lo que realmente necesita. Como 1.25^3 es aproximadamente 2, eso significa que todo el programa tarda el doble de tiempo en ejecutarse como realmente lo necesita.

En primer lugar, ya que todo el tiempo se dedica a la espera de E/S gprof voy a decir que nada sobre cómo se gasta ese momento, ya que sólo se fija en "funcionamiento" de tiempo.

En segundo lugar, suponga (solo por argumento) que hizo cuente el tiempo de E/S. Podría darle un gráfico de llamadas, básicamente diciendo que cada rutina toma el 100% del tiempo. ¿Qué te dice eso? Nada más de lo que ya sabes.

Sin embargo, si se toma un pequeño número de muestras de la pila, se verá en cada uno de ellos las líneas de código en el que cada rutina llama a la siguiente. En otras palabras, no es sólo que le da una estimación del porcentaje de tiempo en bruto, es que apunta a líneas específicas de código que son costosos. Puede ver cada línea de código y preguntar si hay alguna manera de hacerlo menos veces. Suponiendo que haces esto, obtendrás el factor de 2 aceleración.

Las personas obtienen grandes factores de esta manera. En mi experiencia, la cantidad de niveles de llamadas puede ser fácilmente de 30 o más. Cada llamada parece necesaria, hasta que pregunte si puede evitarse. Incluso un pequeño número de llamadas evitables puede tener un efecto enorme sobre esas muchas capas.

Cuestiones relacionadas