如何在C语言中找到程序的执行时间?

时间:2022-04-05 15:03:32

I'm trying to find a way to get the execution time of a section of code in C. I've already tried both time() and clock() from time.h, but it seems that time() returns seconds and clock() seems to give me milliseconds (or centiseconds?) I would like something more precise though. Is there a way I can grab the time with at least microsecond precision?

我正在寻找一种方法来获取c中代码的执行时间,我已经尝试了time()和clock()。h,但是看起来time()返回秒,而clock()似乎给了我毫秒(还是厘秒?)我想要更精确的东西。有没有一种方法,我可以用至少微秒的精度抓住时间?

This only needs to be able to compile on Linux.

这只需要能够在Linux上编译。

11 个解决方案

#1


15  

You referred to clock() and time() - were you looking for gettimeofday()? That will fill in a struct timeval, which contains seconds and microseconds.

您提到了clock()和time()——您是在寻找gettimeofday()吗?这将填充一个包含秒和微秒的struct timeval。

Of course the actual resolution is up to the hardware.

当然,实际的分辨率取决于硬件。

#2


12  

For what it's worth, here's one that's just a few macros:

值得注意的是,这里有几个宏:

#include <time.h>
clock_t startm, stopm;
#define START if ( (startm = clock()) == -1) {printf("Error calling clock");exit(1);}
#define STOP if ( (stopm = clock()) == -1) {printf("Error calling clock");exit(1);}
#define PRINTTIME printf( "%6.3f seconds used by the processor.", ((double)stopm-startm)/CLOCKS_PER_SEC);

Then just use it with:

然后用在:

main() {
  START;
  // Do stuff you want to time
  STOP;
  PRINTTIME;
}

From http://ctips.pbwiki.com/Timer

从http://ctips.pbwiki.com/Timer

#3


11  

You want a profiler application.

您需要一个分析器应用程序。

Search keywords at SO and search engines: linux profiling

搜索关键字在SO和搜索引擎:linux剖析

#4


3  

Have a look at gettimeofday, clock_*, or get/setitimer.

看看gettimeofday, clock_*,或者get/setitimer。

#5


2  

Try "bench.h"; it lets you put a START_TIMER; and STOP_TIMER("name"); into your code, allowing you to arbitrarily benchmark any section of code (note: only recommended for short sections, not things taking dozens of milliseconds or more). Its accurate to the clock cycle, though in some rare cases it can change how the code in between is compiled, in which case you're better off with a profiler (though profilers are generally more effort to use for specific sections of code).

试着“bench.h”;它让你放一个START_TIMER;和STOP_TIMER(“名字”);在您的代码中,允许您任意地对任何代码段进行基准测试(注意:只推荐使用短的代码段,而不建议使用几十毫秒或更长时间的代码)。它精确到时钟周期,但是在一些罕见的情况下,它可以更改中间的代码的编译方式,在这种情况下,您最好使用分析器(尽管分析器通常更努力地用于代码的特定部分)。

It only works on x86.

它只在x86上工作。

#6


1  

You might want to google for an instrumentation tool.

您可能想要谷歌作为一个工具。

#7


1  

You won't find a library call which lets you get past the clock resolution of your platform. Either use a profiler (man gprof) as another poster suggested, or - quick & dirty - put a loop around the offending section of code to execute it many times, and use clock().

您不会找到一个库调用,它允许您通过平台的时钟分辨率。要么按照另一个海报的建议使用profiler (man gprof),要么——quick & dirty——对违规代码段进行循环,多次执行,然后使用clock()。

#8


1  

gettimeofday() provides you with a resolution of microseconds, whereas clock_gettime() provides you with a resolution of nanoseconds.

gettimeofday()为您提供了一个微秒的分辨率,而clock_gettime()为您提供了一个毫微秒的分辨率。

int clock_gettime(clockid_t clk_id, struct timespec *tp);

The clk_id identifies the clock to be used. Use CLOCK_REALTIME if you want a system-wide clock visible to all processes. Use CLOCK_PROCESS_CPUTIME_ID for per-process timer and CLOCK_THREAD_CPUTIME_ID for a thread-specific timer.

clk_id标识要使用的时钟。如果希望系统范围内的时钟对所有进程可见,请使用CLOCK_REALTIME。每个进程计时器使用CLOCK_PROCESS_CPUTIME_ID,特定于线程的计时器使用CLOCK_THREAD_CPUTIME_ID。

#9


0  

It depends on the conditions.. Profilers are nice for general global views however if you really need an accurate view my recommendation is KISS. Simply run the code in a loop such that it takes a minute or so to complete. Then compute a simple average based on the total run time and iterations executed.

这要看情况而定。概要文件对于一般的全局视图是很好的,但是如果你真的需要一个准确的视图,我的建议是KISS。只需在循环中运行代码,使其需要一分钟左右的时间来完成。然后根据执行的总运行时间和迭代计算一个简单的平均值。

This approach allows you to:

这种方法使您能够:

  1. Obtain accurate results with low resolution timers.

    用低分辨率的定时器获得精确的结果。

  2. Not run into issues where instrumentation interferes with high speed caches (l2,l1,branch..etc) close to the processor. However running the same code in a tight loop can also provide optimistic results that may not reflect real world conditions.

    不要遇到仪器干扰高速缓存(l2、l1、branch等)靠近处理器的问题。然而,在紧密循环中运行相同的代码也可以提供乐观的结果,而这些结果可能不能反映真实的情况。

#10


0  

Don't know which enviroment/OS you are working on, but your timing may be inaccurate if another thread, task, or process preempts your timed code in the middle. I suggest exploring mechanisms such as mutexes or semaphores to prevent other threads from preemting your process.

不知道您正在处理哪个环境/操作系统,但是如果另一个线程、任务或进程在中间抢占了您的时间代码,您的时间可能不准确。我建议探索一些机制,如互斥体或信号量,以防止其他线程对进程进行预处理。

#11


0  

If you are developing on x86 or x64 why not use the Time Stamp Counter: RDTSC.

如果您正在x86或x64上开发,为什么不使用时间戳计数器:RDTSC。

It will be more reliable then Ansi C functions like time() or clock() as RDTSC is an atomic function. Using C functions for this purpose can introduce problems as you have no guarantee that the thread they are executing in will not be switched out and as a result the value they return will not be an accurate description of the actual execution time you are trying to measure.

它将比Ansi C函数(如time()或clock()更可靠,因为RDTSC是一个原子函数。为此目的使用C函数可能会带来问题,因为您无法保证它们正在执行的线程不会被切换出去,因此它们返回的值将不能准确地描述您试图度量的实际执行时间。

With RDTSC you can better measure this. You will need to convert the tick count back into a human readable time H:M:S format which will depend on the processors clock frequency but google around and I am sure you will find examples.

使用RDTSC,您可以更好地度量这一点。您将需要将滴答计数转换回人类可读的H:M:S格式,这将取决于处理器的时钟频率,但谷歌,我相信您会找到示例。

However even with RDTSC you will be including the time your code was switched out of execution, while a better solution than using time()/clock() if you need an exact measurement you will have to turn to a profiler that will instrument your code and take into account when your code is not actually executing due to context switches or whatever.

然而即使RDTSC你将包括执行代码转换的时候,虽然比使用时间()/时钟更好的解决方案()如果你需要准确的测量你将不得不转向一个分析器工具代码和考虑当你的代码实际上并不是由于执行上下文切换等等。

#1


15  

You referred to clock() and time() - were you looking for gettimeofday()? That will fill in a struct timeval, which contains seconds and microseconds.

您提到了clock()和time()——您是在寻找gettimeofday()吗?这将填充一个包含秒和微秒的struct timeval。

Of course the actual resolution is up to the hardware.

当然,实际的分辨率取决于硬件。

#2


12  

For what it's worth, here's one that's just a few macros:

值得注意的是,这里有几个宏:

#include <time.h>
clock_t startm, stopm;
#define START if ( (startm = clock()) == -1) {printf("Error calling clock");exit(1);}
#define STOP if ( (stopm = clock()) == -1) {printf("Error calling clock");exit(1);}
#define PRINTTIME printf( "%6.3f seconds used by the processor.", ((double)stopm-startm)/CLOCKS_PER_SEC);

Then just use it with:

然后用在:

main() {
  START;
  // Do stuff you want to time
  STOP;
  PRINTTIME;
}

From http://ctips.pbwiki.com/Timer

从http://ctips.pbwiki.com/Timer

#3


11  

You want a profiler application.

您需要一个分析器应用程序。

Search keywords at SO and search engines: linux profiling

搜索关键字在SO和搜索引擎:linux剖析

#4


3  

Have a look at gettimeofday, clock_*, or get/setitimer.

看看gettimeofday, clock_*,或者get/setitimer。

#5


2  

Try "bench.h"; it lets you put a START_TIMER; and STOP_TIMER("name"); into your code, allowing you to arbitrarily benchmark any section of code (note: only recommended for short sections, not things taking dozens of milliseconds or more). Its accurate to the clock cycle, though in some rare cases it can change how the code in between is compiled, in which case you're better off with a profiler (though profilers are generally more effort to use for specific sections of code).

试着“bench.h”;它让你放一个START_TIMER;和STOP_TIMER(“名字”);在您的代码中,允许您任意地对任何代码段进行基准测试(注意:只推荐使用短的代码段,而不建议使用几十毫秒或更长时间的代码)。它精确到时钟周期,但是在一些罕见的情况下,它可以更改中间的代码的编译方式,在这种情况下,您最好使用分析器(尽管分析器通常更努力地用于代码的特定部分)。

It only works on x86.

它只在x86上工作。

#6


1  

You might want to google for an instrumentation tool.

您可能想要谷歌作为一个工具。

#7


1  

You won't find a library call which lets you get past the clock resolution of your platform. Either use a profiler (man gprof) as another poster suggested, or - quick & dirty - put a loop around the offending section of code to execute it many times, and use clock().

您不会找到一个库调用,它允许您通过平台的时钟分辨率。要么按照另一个海报的建议使用profiler (man gprof),要么——quick & dirty——对违规代码段进行循环,多次执行,然后使用clock()。

#8


1  

gettimeofday() provides you with a resolution of microseconds, whereas clock_gettime() provides you with a resolution of nanoseconds.

gettimeofday()为您提供了一个微秒的分辨率,而clock_gettime()为您提供了一个毫微秒的分辨率。

int clock_gettime(clockid_t clk_id, struct timespec *tp);

The clk_id identifies the clock to be used. Use CLOCK_REALTIME if you want a system-wide clock visible to all processes. Use CLOCK_PROCESS_CPUTIME_ID for per-process timer and CLOCK_THREAD_CPUTIME_ID for a thread-specific timer.

clk_id标识要使用的时钟。如果希望系统范围内的时钟对所有进程可见,请使用CLOCK_REALTIME。每个进程计时器使用CLOCK_PROCESS_CPUTIME_ID,特定于线程的计时器使用CLOCK_THREAD_CPUTIME_ID。

#9


0  

It depends on the conditions.. Profilers are nice for general global views however if you really need an accurate view my recommendation is KISS. Simply run the code in a loop such that it takes a minute or so to complete. Then compute a simple average based on the total run time and iterations executed.

这要看情况而定。概要文件对于一般的全局视图是很好的,但是如果你真的需要一个准确的视图,我的建议是KISS。只需在循环中运行代码,使其需要一分钟左右的时间来完成。然后根据执行的总运行时间和迭代计算一个简单的平均值。

This approach allows you to:

这种方法使您能够:

  1. Obtain accurate results with low resolution timers.

    用低分辨率的定时器获得精确的结果。

  2. Not run into issues where instrumentation interferes with high speed caches (l2,l1,branch..etc) close to the processor. However running the same code in a tight loop can also provide optimistic results that may not reflect real world conditions.

    不要遇到仪器干扰高速缓存(l2、l1、branch等)靠近处理器的问题。然而,在紧密循环中运行相同的代码也可以提供乐观的结果,而这些结果可能不能反映真实的情况。

#10


0  

Don't know which enviroment/OS you are working on, but your timing may be inaccurate if another thread, task, or process preempts your timed code in the middle. I suggest exploring mechanisms such as mutexes or semaphores to prevent other threads from preemting your process.

不知道您正在处理哪个环境/操作系统,但是如果另一个线程、任务或进程在中间抢占了您的时间代码,您的时间可能不准确。我建议探索一些机制,如互斥体或信号量,以防止其他线程对进程进行预处理。

#11


0  

If you are developing on x86 or x64 why not use the Time Stamp Counter: RDTSC.

如果您正在x86或x64上开发,为什么不使用时间戳计数器:RDTSC。

It will be more reliable then Ansi C functions like time() or clock() as RDTSC is an atomic function. Using C functions for this purpose can introduce problems as you have no guarantee that the thread they are executing in will not be switched out and as a result the value they return will not be an accurate description of the actual execution time you are trying to measure.

它将比Ansi C函数(如time()或clock()更可靠,因为RDTSC是一个原子函数。为此目的使用C函数可能会带来问题,因为您无法保证它们正在执行的线程不会被切换出去,因此它们返回的值将不能准确地描述您试图度量的实际执行时间。

With RDTSC you can better measure this. You will need to convert the tick count back into a human readable time H:M:S format which will depend on the processors clock frequency but google around and I am sure you will find examples.

使用RDTSC,您可以更好地度量这一点。您将需要将滴答计数转换回人类可读的H:M:S格式,这将取决于处理器的时钟频率,但谷歌,我相信您会找到示例。

However even with RDTSC you will be including the time your code was switched out of execution, while a better solution than using time()/clock() if you need an exact measurement you will have to turn to a profiler that will instrument your code and take into account when your code is not actually executing due to context switches or whatever.

然而即使RDTSC你将包括执行代码转换的时候,虽然比使用时间()/时钟更好的解决方案()如果你需要准确的测量你将不得不转向一个分析器工具代码和考虑当你的代码实际上并不是由于执行上下文切换等等。