2011-01-07 11 views
8

Pracuję nad porównaniem wydajności sterownika SDIO UART Linux/Android i używam current_kernel_time() na początku i końcu analizowanej funkcji odczytu i zapisu, a następnie drukowania różnicy czasu.Jak niezawodne jest current_kernel_time()?

W większości przypadków różnica czasu wynosi 0 (zero) nanosekund (niezależnie od wielkości danych do odczytu/zapisu: 16-2048 bajtów), co logicznie uważam za nieprawidłowe, tylko kilka razy dostaję trochę wartości mam nadzieję, że są poprawne.

Jak wiarygodny jest current_kernel_time()?

Dlaczego najczęściej uzyskuję 0ns?

Mam zamiar profil na poziomie jądra, aby uzyskać więcej details..before że ktoś może rzucić nieco światła na to behavior..has ktoś obserwuje się czegoś takiego ...

Również wszelkie sugestie, aby pomóc/poprawcie moje podejście do benchmarkingu są również mile widziane!

Dziękuję.

EDYTOWANIE:
To jest odczytany kod z jądra Linuksa w wersji 2.6.32.9. Po dodaniu current_kernel_time() jak poniżej, w # 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

Dlaczego nie wyświetlasz kodu? Trudno powiedzieć, co jest nie tak z czymś, czego nie możesz zobaczyć. –

+0

Jaka platforma? Tego typu pytanie jest dość specyficzne dla sprzętu (lub przynajmniej specyficzne dla architektury). –

+0

Dzięki za komentarze. Dodałem kod. Próbuję tego na Linuxie (32-bitowy laptop Dell) oraz na Androidzie (Android Dev Phone). – TheCottonSilk

Odpowiedz

10

current_kernel_time jest przeznaczona do pomiaru czasu, a nie do pomiaru wydajności. Powraca, wartość, nie oparta na aktualnym czasomierzu, ale na wartości czasu, która jest aktualizowana przez przerwanie zegara. Tak więc dokładność zależy od czasu przerwania timera. , a otrzymasz słabą rozdzielczość.

Jednak być może getnstimeofday, jest bardziej odpowiedni do Twoich potrzeb, ponieważ odczytywał on również aktualne źródło zegara, aby dostosować wartość czasu. Powinien być bardziej drobnoziarnisty.

Na podstawie jądra source, może najlepszą funkcją jest getrawmonotonic, w mało prawdopodobnym przypadku, gdy czas systemowy zostanie skorygowany do tyłu podczas pomiaru.

+0

Dzięki, shodanex! getnstimeofday() podaje stałe wartości czasu w ns, ponieważ logicznie spodziewane liczby zwiększają się względnie wraz ze wzrostem rozmiaru danych. – TheCottonSilk

Powiązane problemy