在编译时发现可用的时钟类型

时间:2015-09-04 12:30:17

标签: c gcc clang

[Ubuntu 14.04,3.16.0-34-generic Kernel,GCC 4.8.4,Clang 3.5.0]

我正在为我的应用程序编写一些经过时间的性能例程,我想以跨平台的方式进行。
我想以这样的方式编写它,即在编译期间选择正确的时钟类型,而不是运行时(我可以通过测试失败和使用回退来完成)。

clock_getres(2)手册页指出:

On POSIX systems on which these functions are available, the symbol _POSIX_TIMERS is defined in <unistd.h> to a value greater than 0. The symbols _POSIX_MONOTONIC_CLOCK, _POSIX_CPUTIME, _POSIX_THREAD_CPUTIME indicate that CLOCK_MONOTONIC, CLOCK_PROCESS_CPUTIME_ID, CLOCK_THREAD_CPUTIME_ID are available. (See also sysconf(3).)

我已经包含在我的代码中,但是我的条件编译语句无法识别符号_POSIX_MONOTONIC_CLOCK。它始终打印'gettimeofday'消息。我尝试过GCC和Clang但得到的结果相同。
我的下面的代码是不完整的(并且不正确),我将非常感谢如何做到这一点。

#include <unistd.h>
#include <features.h>
#include <stdio.h>    // printf (otherwise forward declaration warning)
#include <stdlib.h>   // NULL
#include <sys/time.h>

long long get_utime(void)
{
        struct timeval tv;
        if (gettimeofday(&tv, NULL) == -1) return -1LL;

        long long t = (long long) tv.tv_usec +
                        (long long) tv.tv_sec * 1000000LL;
        return t;
}


int main() {

  union time{
    struct timespec tSpec;
    long long tLL;
  } myT;

#ifdef CLOCK_MONOTONIC_RAW
  clock_gettime(CLOCK_MONOTONIC_RAW, &myT.tSpec);
  printf("CLOCK_MONOTONIC_RAW\n");
#elif _POSIX_MONOTONIC_CLOCK
  clock_gettime(CLOCK_MONOTONIC, &myT.tSpec);
  printf("CLOCK_MONOTONIC\n");
#else
  myT.tLL = get_utime();
  printf("gettimeofday\n");
#endif // CLOCK_MONOTONIC_RAW

  return 0;
}

我没有使用任何配置或自动配置软件。

此外,关于CLOCK_MONOTONIC&amp;的相对速度的评论。 CLOCK_MONOTONIC_RAW会很好。我理解它们的区别和局限性。

1 个答案:

答案 0 :(得分:3)

您没有声明man页面所说的标题和功能测试宏。这有效:

#define _POSIX_C_SOURCE     200809L  // <- This was missing.
#define _XOPEN_SOURCE       700      // <- This is optional.

#include <unistd.h>
#include <stdio.h>    // printf (otherwise forward declaration warning)
#include <stdlib.h>   // NULL
#include <sys/time.h>
#include <time.h>     // <- This was missing.

long long get_utime(void)
{
        struct timeval tv;
        if (gettimeofday(&tv, NULL) == -1) return -1LL;

        long long t = (long long) tv.tv_usec +
                        (long long) tv.tv_sec * 1000000LL;
        return t;
}


int main() {

  union time{
    struct timespec tSpec;
    long long tLL;
  } myT;

#ifdef CLOCK_MONOTONIC_RAW
  clock_gettime(CLOCK_MONOTONIC_RAW, &myT.tSpec);
  printf("CLOCK_MONOTONIC_RAW\n");
#elif _POSIX_MONOTONIC_CLOCK
  clock_gettime(CLOCK_MONOTONIC, &myT.tSpec);
  printf("CLOCK_MONOTONIC\n");
#else
  myT.tLL = get_utime();
  printf("gettimeofday\n");
#endif // CLOCK_MONOTONIC_RAW

  return 0;
}