2016-05-10 11 views
1

次のように私は(私の.hファイルで指定され、実装されている)2つのインライン関数を使用することにより、総経過時間を収集しています:Cで処理時間を収集する方法は?

extern double _elapsed_time_mf; 
extern double _elapsed_time_b; 

//this function returns the elapsed time in order to compute the total elapsed time of an operation 
static inline struct timeval get_current_time() { 
    struct timeval time; 
    gettimeofday(&time, NULL); 
    return time; 
} 

//calculate the total processed time and return the elapsed total time in seconds 
static inline double get_elapsed_time(struct timeval start, struct timeval end) { 
    long int tmili; 
    tmili = (int) (1000.0 * (end.tv_sec - start.tv_sec) + 
      (end.tv_usec - start.tv_usec)/1000.0); 

    return (double) (tmili/(double) 1000.0); 
} 

その後、私は私が行う操作の合計経過時間を知りたいの際これは:

void my_function() { 
#ifdef COLLECT_STATISTICAL_DATA 
    struct timeval start; 
    struct timeval end; 

    start = get_current_time(); 
#endif 

    //a processing.... 

#ifdef COLLECT_STATISTICAL_DATA 
    end = get_current_time(); 

    _elapsed_time_mf = get_elapsed_time(start, end); 
#endif 
} 

_elapsed_time_mf一つだけ.cファイルで定義されています。

しかし、私は奇妙な結果を得ています。たとえば、function_bという別の関数があるとします。この関数は経過時間(他のグローバル変数に格納されています)も収集します。次に、この関数はmy_function(前のコードに従って経過時間を収集する)を呼び出します。ただし、合計経過時間がfunction_bの場合は、my_functionの合計経過時間よりも小さい場合があります。このような状況の例は次のとおりです。たまに

void function_b() { 
#ifdef COLLECT_STATISTICAL_DATA 
    struct timeval start; 
    struct timeval end; 

    start = get_current_time(); 
#endif 

    //a processing.... 
    my_function();  
    //another processing... 

#ifdef COLLECT_STATISTICAL_DATA 
    end = get_current_time(); 

    _elapsed_time_b = get_elapsed_time(start, end); 
#endif 
} 

_elapsed_time_b_elapsed_time_mfよりも低いです。どうして? クロック/日付/タイムスタンプ(CPU経過時間ではありません)に従って経過時間を秒単位で収集したいと思います。

+2

'gettimeofday'はタイミング情報を収集するための非常に悪いです:

私の機能は今のように記述されています。それは静的な周波数を持たず、いくつかのシステム/構成では逆方向に進むことができます。これはあなたの場合に起こることではありませんが、心に留めておく価値があります。 – Art

+0

@Artあなたは何をお勧めしますか? –

+1

'clock_gettime'と' CLOCK_MONOTONIC'を最小限に抑えて(単調な時計の更新以上を保証するシステム特有の改善があります)、システムにそれがない場合は、少なくとも保証されないより良い時間関数を見てください後方に。 'gettimeofday'は、後ろに行く、前に飛ぶ、周波数を変更するなどの理由で、最悪のケースです。 – Art

答えて

0

アートがコメントしたように、私はclock_gettimeを使用しています。したがって、私のコードは現在、期待どおりに動作しています。

static inline double get_elapsed_time(struct timespec start, struct timespec end) {   
    double start_in_sec = (double)start.tv_sec + (double)start.tv_nsec/1000000000.0; 
    double end_in_sec = (double)end.tv_sec + (double)end.tv_nsec/1000000000.0; 
    return end_in_sec - start_in_sec; 
} 

static inline struct timespec get_current_time() { 
    struct timespec time; 
    clock_gettime(CLOCK_MONOTONIC, &time); 
    return time; 
} 
+1

ああ、それは 'gettimeofday'に関連していました。クール。私の推測が助けてくれてうれしいです。 – Art

0

get_elapsed_timeの実装を再検討したいことがあります。ここから:http://www.gnu.org/software/libc/manual/html_node/Elapsed-Time.html

int timeval_subtract (struct timeval *result, struct timeval *x, struct timeval *y) 
{ 
    /* Perform the carry for the later subtraction by updating y. */ 
    if (x->tv_usec < y->tv_usec) { 
    int nsec = (y->tv_usec - x->tv_usec)/1000000 + 1; 
    y->tv_usec -= 1000000 * nsec; 
    y->tv_sec += nsec; 
    } 
    if (x->tv_usec - y->tv_usec > 1000000) { 
    int nsec = (x->tv_usec - y->tv_usec)/1000000; 
    y->tv_usec += 1000000 * nsec; 
    y->tv_sec -= nsec; 
    } 

    /* Compute the time remaining to wait. 
    tv_usec is certainly positive. */ 
    result->tv_sec = x->tv_sec - y->tv_sec; 
    result->tv_usec = x->tv_usec - y->tv_usec; 

    /* Return 1 if result is negative. */ 
    return x->tv_sec < y->tv_sec; 
} 
+0

私は理解しました。しかし、私は結果を二重値とし、経過時間を秒で求めます。この場合、どのように変換できますか? –

+0

'double dif = result-> tv_sec; double usec = result-> tv_usec; dif + = usec/1000000。 ' 何かのように... –

関連する問題