2011-01-07 6 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의 읽기 코드입니다.

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

의견을 보내 주셔서 감사합니다. 코드를 추가했습니다. 나는 리눅스 (32 비트 델 노트북)뿐만 아니라 안드로이드 (안드로이드 개발 전화)에서 이것을 시도하고있다. – TheCottonSilk

답변

10

current_kernel_time이없는 성능 측정을 위해, 계시위한 것입니다 : ifdef를-ENDIF 나는 #에서 다음과 같이 current_kernel_time()를 추가했다. 실제 타이머를 기반으로하지 않고 타이머 인터럽트에 의해 업데이트되는 시간 값을 기준으로 값을 반환합니다. 따라서 정밀도는 타이머 인터럽트주기에 따라 다릅니다. 그리고 해상도가 떨어집니다.

그러나 실제로는 getnstimeofday이 시간 값을 조정하기 위해 실제 클럭 소스를 읽으므로 사용자의 요구에 더 적합합니다. 더 세밀해야합니다.

커널 source을 기반으로 측정하는 동안 드물게 시스템 시간이 뒤로 조정되는 경우 최상의 기능은 getrawmonotonic입니다.

+0

감사합니다, shodanex! getnstimeofday()는 논리적으로 예상되는 데이터 크기의 증가에 따라 상대적으로 숫자가 증가하므로 ns에서 일관된 시간 값을 제공합니다. – TheCottonSilk

관련 문제