5

私は64ビットのUbuntu 12.04システムを使用しており、次のコードを試しました:

#include <unistd.h>
#include <time.h>
#include <stdio.h>


int
main(void)
{
  struct timespec user1,user2;
  struct timespec sys1,sys2;
  double user_elapsed;
  double sys_elapsed;

  clock_gettime(CLOCK_REALTIME, &user1);
  clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &sys1);
  sleep(10);
  clock_gettime(CLOCK_REALTIME, &user2);
  clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &sys2);
  user_elapsed = user2.tv_sec + user2.tv_nsec/1E9;
  user_elapsed -= user1.tv_sec + user1.tv_nsec/1E9;
  printf("CLOCK_REALTIME: %f\n", user_elapsed);
  sys_elapsed = sys2.tv_sec + sys2.tv_nsec/1E9;
  sys_elapsed -= sys1.tv_sec + sys1.tv_nsec/1E9;
  printf("CLOCK_PROCESS_CPUTIME_ID: %f\n", sys_elapsed);
}

私が理解しているように、これは次のように出力する必要があります

CLOCK_REALTIME: 10.000117
CLOCK_PROCESS_CPUTIME_ID: 10.001

しかし、私の場合、私が得るのは

CLOCK_REALTIME: 10.000117
CLOCK_PROCESS_CPUTIME_ID: 0.000032

これは正しい動作ですか?もしそうなら、どうすればsys1とsys2の実際の秒数を知ることができますか?

CLOCK_PROCESS_CPUTIME_ID を CLOCK_REALTIME に変更すると、期待どおりの結果が得られますが、精度が必要なため、それは私が望むものではありません。

[編集] どうやら CLOCK_PROCESS_CPUTIME_ID は、CPU が処理に費やした実際の時間を返します。CLOCK_MONOTONIC は正しい値を返すようです。しかし、どの程度の精度で?

4

1 に答える 1

6

基本的に必要なのは、アプリケーションの現在の実行時間をマイクロ秒単位で正確に取得することだけです。

ここでの実行時間とは、誤解しない限り、経過時間のことです。通常CLOCK_REALTIMEはそれでよいのですが、アプリケーションの実行中に時間が設定されると、CLOCK_REALTIMEの経過時間の概念も変わります。それを防ぐために、可能性は低いかもしれませんが、CLOCK_MONOTONICまたは、存在する場合は、を使用することをお勧めしCLOCK_MONOTONIC_RAWます。マニュアルページの説明から

   CLOCK_REALTIME
          System-wide real-time clock.  Setting this clock requires appro-
          priate privileges.

   CLOCK_MONOTONIC
          Clock that cannot be set and  represents  monotonic  time  since
          some unspecified starting point.

   CLOCK_MONOTONIC_RAW (since Linux 2.6.28; Linux-specific)
          Similar  to  CLOCK_MONOTONIC, but provides access to a raw hard-
          ware-based time that is not subject to NTP adjustments.

CLOCK_MONOTONICNTP 調整の影響を受ける可能性がありますが、そうでCLOCK_MONOTONIC_RAWはありません。これらすべてのクロックは通常、1 ナノ秒の分解能を持っています ( で確認してclock_getres()ください) が、目的には 1 マイクロ秒未満の分解能で十分です。

経過時間をマイクロ秒単位で計算するには

#define USED_CLOCK CLOCK_MONOTONIC // CLOCK_MONOTONIC_RAW if available
#define NANOS 1000000000LL

int main(int argc, char *argv[]) {
    /* Whatever */
    struct timespec begin, current;
    long long start, elapsed, microseconds;
    /* set up start time data */
    if (clock_gettime(USED_CLOCK, &begin)) {
        /* Oops, getting clock time failed */
        exit(EXIT_FAILURE);
    }
    /* Start time in nanoseconds */
    start = begin.tv_sec*NANOS + begin.tv_nsec;

    /* Do something interesting */

    /* get elapsed time */
    if (clock_gettime(USED_CLOCK, &current)) {
        /* getting clock time failed, what now? */
        exit(EXIT_FAILURE);
    }
    /* Elapsed time in nanoseconds */
    elapsed = current.tv_sec*NANOS + current.tv_nsec - start;
    microseconds = elapsed / 1000 + (elapsed % 1000 >= 500); // round up halves

    /* Display time in microseconds or something */

    return EXIT_SUCCESS;
}
于 2012-08-10T14:09:22.107 に答える