2011-01-07 4 views
8

私はSDIO UART Linux/Androidドライバのパフォーマンスベンチマークに取り組んでおり、分析対象の読み込み、書き込み機能の実装の開始時と終了時にcurrent_kernel_time()を使用してから時間差を表示しています。current_kernel_time()の信頼性はどれくらいですか?

ほとんどの場合、論理的に私が間違っていると思う、0(ゼロ)ナノ秒(読み書きするデータのサイズにかかわらず:16-2048バイト)の時間差がほとんどあります。うまくいけば価値が正しいと思います。

current_kernel_time()の信頼性はどれくらいですか?

なぜほとんどの時間が0nsになるのですか?私は、これは誰もが前に、このような何かを観察behavior..hasに誰かがいくつかの光を投げることができ、よりdetails..beforeを取得するために、カーネルレベルでプロファイリングする予定です

...

また

、任意の提案を支援します/ベンチマークに私のアプローチを修正することも歓迎です!

ありがとうございます。

編集:
これはLinuxカーネルバージョン2.6.32.9の読み取りコードです。 IはIFDEF-ENDIF#下で、以下のように)(current_kernel_timeを追加:

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

なぜコードを表示しないのですか?あなたが見ることができないものが間違っていると言うのは難しいです。 –

+0

どのプラットフォームですか?このタイプの質問はかなりハードウェア固有のものです(または少なくともアーキテクチャー固有のもの) –

+0

コメントありがとうございます。私はコードを追加しました。私はLinux(32 bit Dell Laptop)とAndroid(Android Dev Phone)でこれを試しています。 – TheCottonSilk

答えて

10

current_kernel_timeを計時するためではなく、性能測定のために意味されます。 実際のタイマーに基づくのではなく、タイマー割り込みによって更新される値に値を返します。したがって、精度はタイマの割り込み周期に依存します。 あなたは解像度が低くなります。

しかし、おそらくgetnstimeofdayは、時間値を調整するために実際のクロックソースも読み取るため、必要に応じてより適しています。それはより細粒でなければならない。

カーネルsourceに基づいて、システム時間が測定中に後方に調整されることはほとんどありませんが、おそらく最も良い機能はgetrawmonotonicです。

+0

ありがとう、shodanex! getnstimeofday()は、データサイズの増加に伴って数値が相対的に増加すると論理的に予想されるため、nsで一貫した時間値を与えます。 – TheCottonSilk

関連する問題