性能分析器:如何使用无符号长度来测量时间(以微秒为单位)?

时间:2010-12-16 23:31:10

标签: c++ c

我正在使用unsigned long收集性能数据,同时分析应用程序,如下所示

  1. unsigned long time_taken = (unsigned long) ((finish_time_in_nano_sec - start_time_in_nano_sec)/1000);

  2. 将time_taken写入文件。对我在我的应用程序中调用的每个函数执行此操作。

  3. 现在应用程序执行后,让一个单独的程序读取上述文件并总结每个功能所需的时间,包括呼叫计数,如

  4. func_name aggregate_time call_counts

    我遇到的问题是,对于某些函数,aggregate_time字段是一个20位的值,即unsigned long可以容纳的最大值。这不可能是真的,因为我以微秒为单位测量时间并且不会运行我的应用程序超过20秒。那么它怎么可能是一个20位数值呢?

    您是否在步骤1,2和3中看到错误?

    此致 克里希纳

    修改

    1)时间测量:     clock_gettime(CLOCK_REALTIME,& start_time);     clock_gettime(CLOCK_REALTIME,& finish_time);     unsigned long time_taken =(unsigned long)((finish_time.tv_nsec - art_time.tv_nsec)/ 1000);

    2)文件写入:     fwrite(& time_taken,sizeof(unsigned long),1,datafile);

    3)文件读取:     fread(& time_taken,sizeof(long),1,datafile);

3 个答案:

答案 0 :(得分:5)

问题在于您的时间测量代码:

clock_gettime(CLOCK_REALTIME, &start_time);
clock_gettime(CLOCK_REALTIME, &finish_time);
unsigned long time_taken = (unsigned long)((finish_time.tv_nsec - start_time.tv_nsec)/1000);

如果start_timefinish_time之间的时钟边界超过1秒,则减法可能会产生负值,然后会转换为非常大的正无符号值。

您还需要考虑时间的tv_sec成员:

unsigned long time_taken;
time_taken = (unsigned long)((finish_time.tv_sec - start_time.tv_sec) * 1000000);
time_taken += (unsigned long)(finish_time.tv_nsec / 1000);
time_taken -= (unsigned long)(start_time.tv_nsec / 1000);

(例如,时钟时间23989032.452秒将表示为struct timespec .tv_sec = 23989032.tv_nsec = 452000000

答案 1 :(得分:1)

问题不在你展示的代码中 - 尽管知道以纳秒为单位的时间类型会很有趣。

因此,问题在于您未显示的代码:

  • 将数据写入文件
  • 从文件中读取数据
  • 以纳秒为单位获取时间
  • 以微秒为单位处理时间

答案 2 :(得分:0)

实际上,在某些情况下可能会获得负面时间。考虑到时间间隔非常小,它们很可能来自使用RDTSC指令,该指令读取计数器,该计数器随CPU的每个时钟递增。在某些多核AMD处理器上,每个核心都有自己的计数器,与其他核心不同步,因此在不同核心上执行的两个连续读数之间的差异可能是负的。

可以通过强制程序在单个内核上执行来轻松解决,例如使用Win32 API SetProcessAffinityMask

编辑:小心你如何衡量时间。大多数时候API具有可怕的分辨率,因此使用它们测量小间隔是没有意义的。请尝试明确使用RDTSC。

最重要的:文件I / O是一个如此慢的功能,它可以完全破坏有用的信息。例如,如果对两者执行测量,调用者和被调用者以及被调用者将结果写入文件,则调用者测量的时间将包括fwrite中花费的时间。监视每次写入,以便您可以看到花费了多少时间(为了避免递归,您可以节省fwrite所花费的时间并使用下一个fwrite进行记录)。