测量处理器在C中滴答作响

时间:2015-07-18 07:37:56

标签: c benchmarking clock

我想计算在函数内执行相同代码时执行时间的差异。然而,令我惊讶的是,当我使用clock()/ clock_t作为启动和停止计时器时,时钟差异有时为0。这是否意味着clock()/ clock_t实际上并不返回处理器在任务上花费的点击次数

经过一些搜索,我觉得clock_gettime()会返回更细粒度的结果。事实确实如此,但我最终得到了一个纳秒(?)秒的数量。它给出了执行时间差异的暗示,但是确切地说它确实有多少点击差异并不准确。我需要做些什么才能找到这个?

#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 Mint 16)上使用 gcc版本4.8.4

2 个答案:

答案 0 :(得分:1)

首先:正如评论中已经提到的那样,一个接一个地执行一次执行可能对你没有好处。如果所有人都下山,那么获得时间的呼叫实际上可能需要比实际执行操作更长的时间。

请计时多次运行(包括预热阶段,以便更换所有内容)并计算平均运行时间。

clock()不保证是单调的。它也不是程序运行的处理器点击次数(无论你定义的是什么)。描述来自clock()的结果的最佳方式可能是“对任何一个CPU花费在计算当前进程上的时间的最佳努力估计”。出于基准测试目的,clock()因此大多无用。

作为per specification

  

clock()函数返回实现对自进程使用的处理器时间的最佳近似值,因为与实现相关的时间仅与进程调用相关。

另外

  

要确定以秒为单位的时间,clock()返回的值应除以宏CLOCKS_PER_SEC的值。

所以,如果你比决议更频繁地致电clock(),那你就不走运了。

对于性能分析/基准测试,您应该 - 如果可能 - 使用现代硬件上可用的性能时钟之一。主要候选人可能是

编辑:现在问题引用CLOCK_PROCESS_CPUTIME_ID,这是Linux暴露TSC的方式。

如果有任何(或两者)可用取决于硬件,也是特定于操作系统。

答案 1 :(得分:0)

在谷歌搜索后,我可以看到clock()函数可以用作标准机制来查找执行的大部分,但要注意时间将根据处理器的负载在不同的时间变化, 您可以使用以下代码进行计算

volumes