2011-01-07 31 views
8

Estoy trabajando en la evaluación comparativa del rendimiento de un controlador SDI UART Linux/Android y usé current_kernel_time() al inicio y al final de la implementación de la función leer, escribir y luego imprimir la diferencia horaria.¿Qué tan confiable es current_kernel_time()?

La mayor parte del tiempo obtengo una diferencia de tiempo de 0 (cero) nanosegundos (independientemente del tamaño de los datos para leer/escribir: 16-2048 bytes) que lógicamente creo que es incorrecto, solo unas pocas veces obtengo valores con suerte esos son correctos.

¿Qué tan confiable es el current_kernel_time()?

¿Por qué obtengo 0ns la mayoría de las veces?

Tengo la intención de perfil a nivel del kernel para obtener más details..before que alguien puede arrojar algo de luz sobre este behavior..has nadie observó nada como esto antes ...

También, alguna sugerencia para ayudar/¡corregir mi enfoque de la evaluación comparativa también es bienvenido!

Gracias.

EDIT:
Este es el código de lectura de la versión del núcleo de Linux 2.6.32.9. Añadí current_kernel_time() como a continuación bajo #ifdef-ENDIF:

static void sdio_uart_receive_chars(struct sdio_uart_port *port, unsigned int *status) 
{ 
#ifdef SDIO_UART_DEBUG 
struct timespec time_spec1, time_spec2; 
time_spec1 = current_kernel_time(); 
#endif 

    struct tty_struct *tty = port->tty; 
    unsigned int ch, flag; 
    int max_count = 256; 

    do { 
     ch = sdio_in(port, UART_RX); 
     flag = TTY_NORMAL; 
     port->icount.rx++; 

     if (unlikely(*status & (UART_LSR_BI | UART_LSR_PE | 
         UART_LSR_FE | UART_LSR_OE))) { 
      /* 
      * For statistics only 
      */ 
      if (*status & UART_LSR_BI) { 
       *status &= ~(UART_LSR_FE | UART_LSR_PE); 
       port->icount.brk++; 
      } else if (*status & UART_LSR_PE) 
       port->icount.parity++; 
      else if (*status & UART_LSR_FE) 
       port->icount.frame++; 
      if (*status & UART_LSR_OE) 
       port->icount.overrun++; 

      /* 
      * Mask off conditions which should be ignored. 
      */ 
      *status &= port->read_status_mask; 
      if (*status & UART_LSR_BI) { 
       flag = TTY_BREAK; 
      } else if (*status & UART_LSR_PE) 
       flag = TTY_PARITY; 
      else if (*status & UART_LSR_FE) 
       flag = TTY_FRAME; 
     } 

     if ((*status & port->ignore_status_mask & ~UART_LSR_OE) == 0) 
      tty_insert_flip_char(tty, ch, flag); 

     /* 
     * Overrun is special. Since it's reported immediately, 
     * it doesn't affect the current character. 
     */ 
     if (*status & ~port->ignore_status_mask & UART_LSR_OE) 
      tty_insert_flip_char(tty, 0, TTY_OVERRUN); 

     *status = sdio_in(port, UART_LSR); 
    } while ((*status & UART_LSR_DR) && (max_count-- > 0)); 
    tty_flip_buffer_push(tty); 

#ifdef SDIO_UART_DEBUG 
time_spec2 = current_kernel_time(); 
printk(KERN_INFO "\n MY_DBG : read took: %ld nanoseconds", 
    (time_spec2.tv_sec - time_spec1.tv_sec) * 1000000000 + (time_spec2.tv_nsec - time_spec1.tv_nsec)); 
#endif 

} 
+0

¿Por qué no muestra algún código? Es difícil decir qué pasa con algo que no puedes ver. –

+0

¿Qué plataforma? Este tipo de pregunta es bastante específica del hardware (o al menos específica de la arquitectura) –

+0

Gracias por los comentarios. He agregado el código. Estoy intentando esto en Linux (Laptop Dell de 32 bits) y en Android (Android Dev Phone). – TheCottonSilk

Respuesta

10

current_kernel_time está destinado para la hora normal, no para la medición del rendimiento. Devuelve, un valor, no basado en un temporizador real, sino en un valor de tiempo que se actualiza mediante una interrupción de temporizador. Entonces la precisión depende del período de interrupción del temporizador. y obtiene una resolución deficiente.

Sin embargo, quizás getnstimeofday, es más adecuado para su necesidad, ya que también lee la fuente de reloj real para ajustar el valor del tiempo. Debería ser más fino.

Basado en kernel source, quizás la mejor función es getrawmonotonic, en el caso improbable de que la hora del sistema se ajuste hacia atrás durante la medición.

+0

Gracias, shodanex! getnstimeofday() proporciona valores de tiempo consistentes en ns, ya que lógicamente se espera que los números aumenten relativamente con el aumento en el tamaño de los datos. – TheCottonSilk

Cuestiones relacionadas