在 C 中测量处理器滴答声
Measuring processor ticks in C
我想计算在函数内执行相同代码时执行时间的差异。然而,令我惊讶的是,当我使用 clock()/clock_t 作为启动和停止计时器时,有时时钟差为 0。这是否意味着 clock()/clock_t 实际上 return 点击次数 处理器花在任务上?
经过一些搜索,在我看来 clock_gettime() 会 return 更细粒度的结果。确实如此,但我最终得到了任意数量的纳秒(?)秒。它暗示了执行时间的差异,但很难准确说明它究竟有多少点击差异。我需要做什么才能找到它?
#include <math.h>
#include <stdio.h>
#include <time.h>
#define M_PI_DOUBLE (M_PI * 2)
void rotatetest(const float *x, const float *c, float *result) {
float rotationfraction = *x / *c;
*result = M_PI_DOUBLE * rotationfraction;
}
int main() {
int i;
long test_total = 0;
int test_count = 1000000;
struct timespec test_time_begin;
struct timespec test_time_end;
float r = 50.f;
float c = 2 * M_PI * r;
float x = 3.f;
float result_inline = 0.f;
float result_function = 0.f;
for (i = 0; i < test_count; i++) {
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &test_time_begin);
float rotationfraction = x / c;
result_inline = M_PI_DOUBLE * rotationfraction;
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &test_time_end);
test_total += test_time_end.tv_nsec - test_time_begin.tv_nsec;
}
printf("Inline clocks %li, avg %f (result is %f)\n", test_total, test_total / (float)test_count,result_inline);
for (i = 0; i < test_count; i++) {
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &test_time_begin);
rotatetest(&x, &c, &result_function);
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &test_time_end);
test_total += test_time_end.tv_nsec - test_time_begin.tv_nsec;
}
printf("Function clocks %li, avg %f (result is %f)\n", test_total, test_total / (float)test_count, result_inline);
return 0;
}
我在 Linux 3.13.0-37-generic (Linux 薄荷 16)
谷歌搜索了一下后,我发现 clock() 函数可以用作查找执行的大部头的标准机制,但请注意,时间会根据负载的不同而有所不同你的处理器,
您可以使用下面的代码进行计算
clock_t begin, end;
double time_spent;
begin = clock();
/* here, do your time-consuming job */
end = clock();
time_spent = (double)(end - begin) / CLOCKS_PER_SEC;
首先:正如评论中已经提到的,一个一个地执行一个 运行 时钟可能对你没有好处。如果一切都走下坡路,获取时间的调用实际上可能比实际执行操作花费的时间更长。
请计算多个 运行 秒的操作(包括预热阶段,以便所有内容都被交换)并计算平均 运行ning 次。
clock()
不保证是单调的。它也不是 处理器点击次数 (无论您将其定义为什么)程序具有 运行。描述 clock()
结果的最佳方式可能是“ 对任何一个 CPU 花费在当前进程计算上的时间的最大努力估计 ”。因此,出于基准测试目的,clock()
几乎没有用。
The clock()
function returns the implementation's best approximation to the processor time used by the process since the beginning of an implementation-dependent time related only to the process invocation.
另外
To determine the time in seconds, the value returned by clock() should be divided by the value of the macro CLOCKS_PER_SEC.
所以,如果你调用 clock()
的次数比解析的次数多,那你就不走运了。
对于 profiling/benchmarking,您应该——如果可能的话——使用现代硬件上可用的一种性能时钟。主要候选人可能是
编辑:问题现在引用 CLOCK_PROCESS_CPUTIME_ID
,这是公开 TSC 的 Linux 方式。
是否有任何(或两者)可用取决于硬件也是操作系统特定的。
我想计算在函数内执行相同代码时执行时间的差异。然而,令我惊讶的是,当我使用 clock()/clock_t 作为启动和停止计时器时,有时时钟差为 0。这是否意味着 clock()/clock_t 实际上 return 点击次数 处理器花在任务上?
经过一些搜索,在我看来 clock_gettime() 会 return 更细粒度的结果。确实如此,但我最终得到了任意数量的纳秒(?)秒。它暗示了执行时间的差异,但很难准确说明它究竟有多少点击差异。我需要做什么才能找到它?
#include <math.h>
#include <stdio.h>
#include <time.h>
#define M_PI_DOUBLE (M_PI * 2)
void rotatetest(const float *x, const float *c, float *result) {
float rotationfraction = *x / *c;
*result = M_PI_DOUBLE * rotationfraction;
}
int main() {
int i;
long test_total = 0;
int test_count = 1000000;
struct timespec test_time_begin;
struct timespec test_time_end;
float r = 50.f;
float c = 2 * M_PI * r;
float x = 3.f;
float result_inline = 0.f;
float result_function = 0.f;
for (i = 0; i < test_count; i++) {
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &test_time_begin);
float rotationfraction = x / c;
result_inline = M_PI_DOUBLE * rotationfraction;
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &test_time_end);
test_total += test_time_end.tv_nsec - test_time_begin.tv_nsec;
}
printf("Inline clocks %li, avg %f (result is %f)\n", test_total, test_total / (float)test_count,result_inline);
for (i = 0; i < test_count; i++) {
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &test_time_begin);
rotatetest(&x, &c, &result_function);
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &test_time_end);
test_total += test_time_end.tv_nsec - test_time_begin.tv_nsec;
}
printf("Function clocks %li, avg %f (result is %f)\n", test_total, test_total / (float)test_count, result_inline);
return 0;
}
我在 Linux 3.13.0-37-generic (Linux 薄荷 16)
谷歌搜索了一下后,我发现 clock() 函数可以用作查找执行的大部头的标准机制,但请注意,时间会根据负载的不同而有所不同你的处理器, 您可以使用下面的代码进行计算
clock_t begin, end;
double time_spent;
begin = clock();
/* here, do your time-consuming job */
end = clock();
time_spent = (double)(end - begin) / CLOCKS_PER_SEC;
首先:正如评论中已经提到的,一个一个地执行一个 运行 时钟可能对你没有好处。如果一切都走下坡路,获取时间的调用实际上可能比实际执行操作花费的时间更长。
请计算多个 运行 秒的操作(包括预热阶段,以便所有内容都被交换)并计算平均 运行ning 次。
clock()
不保证是单调的。它也不是 处理器点击次数 (无论您将其定义为什么)程序具有 运行。描述 clock()
结果的最佳方式可能是“ 对任何一个 CPU 花费在当前进程计算上的时间的最大努力估计 ”。因此,出于基准测试目的,clock()
几乎没有用。
The
clock()
function returns the implementation's best approximation to the processor time used by the process since the beginning of an implementation-dependent time related only to the process invocation.
另外
To determine the time in seconds, the value returned by clock() should be divided by the value of the macro CLOCKS_PER_SEC.
所以,如果你调用 clock()
的次数比解析的次数多,那你就不走运了。
对于 profiling/benchmarking,您应该——如果可能的话——使用现代硬件上可用的一种性能时钟。主要候选人可能是
编辑:问题现在引用 CLOCK_PROCESS_CPUTIME_ID
,这是公开 TSC 的 Linux 方式。
是否有任何(或两者)可用取决于硬件也是操作系统特定的。