【问题标题】:Highly accurate time measurement in CC语言中的高精度时间测量
【发布时间】:2014-06-06 13:31:58
【问题描述】:

我正在尝试找出一种方法来编写一些代码,以准确计算在 BST 上执行搜索所需的时间。目前我正在使用时间,元素总数为 10^5。它看起来像下面这样:-

clock_t begin, end;
begin = clock();
...
...
...
end = clock();
difference = (end-begin)/CLOCKS_PER_SECOND;

但是,这并没有给我我正在寻找的精确度。还有其他我可以使用的 libc 函数吗?

【问题讨论】:

标签: c linux


【解决方案1】:

如果你的库支持它,C11 有 timespec_get(),它的测量时间可达纳秒,具体取决于你的系统时钟分辨率。

【讨论】:

    【解决方案2】:

    要对您的算法进行基准测试,您需要进行一些重复以达到至少数百毫秒的范围。 (这是标准做法)。要对仅发生在用户空间(无线程、系统调用等)的算法进行基准测试,您需要使用 getrusage(RUSAGE_SELF, &r) 并使用包含秒和微秒的 r.ru_utime 值。

    【讨论】:

      【解决方案3】:

      如果您使用 Intel CPU 运行基准测试。也许您可以尝试一下 RDTSC 和 RDTSCP 说明。

      here is a document about the instructions

      【讨论】:

        【解决方案4】:

        英国夏令时?你想要什么样的精度?在 32 位系统上除以 CLOCKS_PER_SECOND 为 10^6 应该得到 6 位精度?

        你会把结果加倍吗?

        试试

        difference = (double)(end-begin)/CLOCKS_PER_SECOND;
        

        注意,diff应该可以容纳double。

        【讨论】:

        • clock() 是准确的,但不是很准确。它通常只精确到大约 50 毫秒。在 Linux 上,它还测量 CPU 时间而不是 wall-time。
        • 是的,我确实使用了双精度——我得到了类似于 0.000000 的输出
        • @Mysticial CPU 时间不是这里需要的吗?搜索 BST 所花费的时间不应该包括其他进程所消耗的时间,这就是 wall time 会给你带来的。
        • @NikosC。无论如何,您不应该对其他活动进程进行基准测试。无论如何,CPU 时间并不是性能的准确衡量标准——尤其是在超线程和涡轮增压等方面。更不用说共享缓存和其他资源争用了。
        • @uki 如果你有 0.000000 你应该用调试器检查 end 和 begin 变量是否包含任何值(或者只是输出到控制台输出等等)。
        【解决方案5】:

        Qt 有QElapsedTimer,它支持高达纳秒的测量。我无法证明它有多准确,IIRC 它在不同平台上使用不同的实现。可悲的是它是 C++,它可能不适合你。另外:

        在不提供纳秒级分辨率的平台上,该值 返回的将是可用的最佳估计值。

        clock() 函数适用于粗略测量,但它在毫秒范围内有效。与它的名字相反,我不认为它以 CPU 时钟为单位进行测量,因为现代处理器的时钟频率可能会有很大差异,因此无法仅依靠 CPU 时钟准确地确定实际时间。 IMO 这个概念可以追溯到 CPU 频率恒定、没有电源管理、没有“涡轮增压”自动超频或其他任何东西的时代。

        编辑:也发现了这个(time.h):

            int clock_gettime(clockid_t clk_id, struct timespec *tp);
        
            ... and the target struct...
        
            struct timespec {
                    time_t   tv_sec;        /* seconds */
                    long     tv_nsec;       /* nanoseconds */
            };
        
        ... and the clock options...
        
        
        CLOCK_REALTIME
            System-wide realtime clock. Setting this clock requires appropriate privileges. 
        CLOCK_MONOTONIC
            Clock that cannot be set and represents monotonic time since some unspecified starting point. 
        CLOCK_PROCESS_CPUTIME_ID
            High-resolution per-process timer from the CPU. 
        CLOCK_THREAD_CPUTIME_ID
            Thread-specific CPU-time clock. 
        

        【讨论】:

          【解决方案6】:

          您所做的与我最近所做的非常相似。

          我确实认为int gettimeofday(struct timeval *tv, struct timezone *tz); 功能适合您的需要。时间信息将被放入struct timeval tv,它以秒和微秒为单位获取时间。手册页中的struct timeval

          struct timeval {
                         time_t      tv_sec;     /* seconds */
                         suseconds_t tv_usec;    /* microseconds */
          };
          

          使用gettimeofday 进行时间测量的简短示例:

          struct timeval time;
          if(gettimeofday( &time, 0 )) return -1;
          
          long cur_time = 1000000 * time.tv_sec + time.tv_usec;
          double sec = cur_time / 1000000.0;
          

          为了方便使用,一个较长的示例已被简化并轻松包装为 c++ 类。代码已放在我的 github 上:https://github.com/lulyon/LinuxTimeCounter,用于实际项目。

          【讨论】:

            猜你喜欢
            • 2010-12-21
            • 1970-01-01
            • 2018-03-17
            • 2017-10-20
            • 1970-01-01
            • 2014-05-08
            • 2013-01-23
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多