用于在C中查找函数调用中的已用时间的计时器

时间:2009-03-12 11:46:16

标签: c profiling timer

我想计算C中函数调用期间经过的时间,精度为1纳秒。

C中是否有可用的定时器功能?

如果是,请提供示例代码段。

伪码

Timer.Start()
foo();
Timer.Stop()
Display time elapsed in execution of foo()

环境详细信息: - 在RHEL计算机上使用gcc 3.4编译器

10 个答案:

答案 0 :(得分:5)

请问您使用的是哪种处理器?如果您使用的是x86处理器,则可以查看时间戳计数器(tsc)。此代码段:

#define rdtsc(low,high) \
     __asm__ __volatile__("rdtsc" : "=a" (low), "=d" (high))

将分别在lowhigh中放置CPU运行的周期数(它需要2 long秒;您可以将结果存储在long long int中)如下:

inline void getcycles (long long int * cycles)
{
  unsigned long low;
  long high;
  rdtsc(low,high);
  *cycles = high; 
  *cycles <<= 32; 
  *cycles |= low; 
}

请注意,这会返回CPU执行的周期数。您需要获得CPU速度,然后计算出每ns的循环次数,以获得经过的ns数。

为了做到这一点,我已经解析了/proc/cpuinfo中的“cpu MHz”字符串,并将其转换为小数。在那之后,它只是一点数学,并记住1MHz =每秒1,000,000个周期,并且有10亿ns /秒。

答案 1 :(得分:4)

在Intel和兼容处理器上,您可以使用rdtsc指令,该指令可以轻松地包装到C代码的asm()块中。它返回内置处理器周期计数器的值,该计数器在每个周期递增。你获得了高分辨率,这样的时间非常快。

要确定您需要校准的增量有多快 - 在固定的时间段(如5秒)内调用此指令两次。如果在将频率转换为功耗降低的处理器上执行此操作,则可能会出现校准问题。

答案 2 :(得分:4)

使用clock_gettime(3)。有关详细信息,请键入man 3 clock_gettime。话虽如此,很少需要纳秒精度。

答案 3 :(得分:2)

任何计时器功能都必须是特定于平台的,特别是在精度要求的情况下。

POSIX系统中的标准解决方案是gettimeofday(),但它只有几微秒的精度。

如果这是用于性能基准测试,标准方法是使测试中的代码花费足够的时间来降低精度要求。换句话说,运行测试代码一秒钟(或更长时间)。

答案 4 :(得分:1)

c中没有定时器,保证1纳秒的精度。您可能需要查看clock()或更好的POSIX gettimeofday()

答案 5 :(得分:0)

我不知道你是否会找到任何提供单纳秒分辨率的定时器 - 它取决于系统时钟的分辨率 - 但你可能想看看http://code.google.com/p/high-resolution-timer/。他们表示,他们可以在大多数Linux系统上提供微秒级别的分辨率,在Sun系统上提供纳秒级分辨率。

答案 6 :(得分:0)

在这种规模上制定基准并不是一个好主意。你有足够的时间来获得最少的时间,如果你在纳秒上工作,这会导致你的结果不可靠。您可以使用平台系统调用或更大规模的boost::Date_Time [首选]。

答案 7 :(得分:0)

你可以跑10到9次然后秒表吗?

答案 8 :(得分:0)

如果您确定如果CPU时间为100%,则可以使用gettimeofday等标准系统调用。我可以想到很多情况,当你执行foo()时,其他线程和进程可能会窃取CPU时间。

答案 9 :(得分:0)

你要求的是这种方式不可能的东西。您需要硬件级别支持才能达到该级别的精度,甚至可以非常小心地控制变量。如果在运行代码时遇到中断会怎样?如果操作系统决定运行其他一些代码怎么办?

你的代码做了什么?它是否使用RAM内存?如果您的代码和/或数据是否在缓存中,该怎么办?

在某些环境中,您可以使用硬件级别计数器执行此作业,前提是您可以控制这些变量。但是,如何防止Linux中的上下文切换?

例如,在德州仪器的DSP工具(Code Composer Studio)中,您可以非常准确地分析代码,因为整个调试环境的设置使得仿真器(例如Blackhawk)接收有关每个操作运行的信息。您还可以在某些处理器中设置直接编码到芯片内部HW块中的观察点。这是有效的,因为内存通道也会路由到此调试块。

他们确实在他们的CSL(芯片支持库)中提供功能,这是您要求的,时间开销是几个周期。但这仅适用于其处理器,完全取决于从HW寄存器读取定时器值。