2011-01-07 152 views
8

我正在研究SDIO UART Linux/Android驅動程序的性能基準測試,並在要分析的讀取,寫入函數實現的開始和結束時使用current_kernel_time(),然後打印時間差。current_kernel_time()有多可靠?

大部分時間我得到的時間差爲0(零)毫微秒(不管讀取/寫入數據的大小:16-2048字節),這在邏輯上我認爲是不正確的,只有很少幾次我得到一些希望這些值是正確的。

current_kernel_time()有多可靠?

爲什麼我大部分時間都得到0ns?

我打算在內核級別來分析,以獲得更多details..before可有人扔一些輕這個behavior..has有人觀察到這樣的事以前......

此外,任何建議,以幫助/更正我的基準測試方法也很受歡迎!

謝謝。編輯:
這是從Linux內核版本2.6.32.9讀取的代碼。我添加current_kernel_time(),如下下的#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

爲什麼你不顯示一些代碼?很難分辨你看不到的東西有什麼問題。 – 2011-01-07 16:12:59

+0

什麼平臺?這種類型的問題非常硬件特定(或至少是特定於架構的) – 2011-01-07 17:11:57

回答

10

current_kernel_time是指用於計時,而不是性能測量。 它返回的值不是基於實際的計時器,而是基於由定時器中斷更新的時間值。所以精度取決於定時器中斷週期。 ,你會得到較差的分辨率。

但是,也許getnstimeofday,更適合您的需要,因爲它也讀取實際的時鐘源來調整時間值。它應該更加細緻。

基於內核source,可能最好的功能是getrawmonotonic,在極少數情況下,系統時間在測量期間向後調整。