为什么 C clock() 返回 0

2024-11-11 08:27:00
admin
原创
46
摘要:问题描述:我有类似这样的事情:clock_t start, end; start=clock(); something_else(); end=clock(); printf(" Clock cycles are: %d - %d ",start,end); 我总是得到输出“时钟周期为...

问题描述:

我有类似这样的事情:

clock_t start, end;
start=clock();

something_else();

end=clock();
printf("
Clock cycles are: %d - %d
",start,end);

我总是得到输出“时钟周期为:0 - 0”

知道为什么会发生这种情况吗?

(仅提供一些细节,something_else()函数使用蒙哥马利表示法执行从左到右的幂运算,而且我不能确定 something_else()函数是否确实花费了一些不可忽略的时间。)

这是在 Linux 上。uname -a 的结果是:

Linux snowy.*****.ac.uk 2.6.32-71.el6.x86_64 #1 SMP Fri May 20 03:51:51 BST 2011 x86_64 x86_64 x86_64 GNU/Linux


解决方案 1:

clock该函数不测量CPU时钟周期。

C 表示clock “返回自仅与程序调用相关的实现定义时代开始以来程序使用的处理器时间的最佳近似值。”

如果您程序的两个连续clock调用之间所花费的时间少于该clock函数的一个单位,那么您可以获得0

POSIXclock将单位定义为CLOCKS_PER_SEC1000000(单位为 1 微秒)。

http://pubs.opengroup.org/onlinepubs/009604499/functions/clock.html

要测量 x86/x64 中的时钟周期,您可以使用内联汇编来检索 CPU 时间戳计数器寄存器的时钟计数rdtsc

解决方案 2:

我猜原因是something_else()消耗的时间太少,超过了的精度clock()。我尝试clock()两次调用,结果和start都是end零,但当我在中间做一些耗时的事情时,结果是合理的。

这是我的测试代码片段:

int main(void) {   
    clock_t start, end;
    start = clock();
    int c;
    for (int i = 0; i < 100; i++) {
        for (int j = 0; j < (1<<30); j++) {
            c++;
        }
    }
    end = clock();
    printf("start = %d, end = %d
", start, end);
    return 0;
}

我的电脑上的结果是:

start = 0, end = 27700000

另外,还有两个建议:

  1. 测试时,不要使用任何编译器优化。你可能认为你的something_else()优化很耗时,但编译器可能会忽略这些操作(尤其是循环),因为它认为它们毫无意义。

  2. 在您的平台上使用sizeof(clock_t)来查看的大小clock_t

解决方案 3:

那么,你希望something_else()花费这些时间吗?试试这个:

#include <sys/time.h>
#include <stdio.h>  
#include <unistd.h>
int main(void) {
    struct timeval start, end;
    long mtime, secs, usecs;    

    gettimeofday(&start, NULL);
    something_else();
    gettimeofday(&end, NULL);
    secs  = end.tv_sec  - start.tv_sec;
    usecs = end.tv_usec - start.tv_usec;
    mtime = ((secs) * 1000 + usecs/1000.0) + 0.5;
    printf("Elapsed time: %ld millisecs
", mtime);
    return 0;
}

解决方案 4:

使用clock()来测量时间的正确方法是:

printf("
Time elapsed: %.2f
",1.0*(end-start)/CLOCKS_PER_SEC);

这是因为 clock_t 不能保证是 int,或者任何其他类型。

解决方案 5:

CLOCKS_PER_SEC检查中的值time.h/clock.h。例如,在我的系统上(Windows 7 上的 Dev Cpp),它仅仅是1000。因此,就我的程序而言,每秒有 1000 个滴答声。您的程序something_else将在几微秒内执行。因此,在clock()函数调用之前和之后都返回零。

在我的系统上,当我something_else用像这样的耗时程序替换你的程序时

for (unsigned i=0xFFFFFFFF;i--;);

start=clock();

for (unsigned i=0xFFFFFFFF;i--;);

end=clock();

我明白了

时钟周期为:10236 - 20593

在其中一个 Linux 机器上,我发现以下内容bits/time.h

/* ISO/IEC 9899:1990 7.12.1: <time.h>
   The macro `CLOCKS_PER_SEC' is the number per second of the value
   returned by the `clock' function. */
/* CAE XSH, Issue 4, Version 2: <time.h>
   The value of CLOCKS_PER_SEC is required to be 1 million on all
   XSI-conformant systems. */
#  define CLOCKS_PER_SEC  1000000l

因此,在分析返回值之前,请考虑这一点clock()

解决方案 6:

我使用了下面的小程序来调查挂钟时间和 CPU 时间。

在我的测试系统上打印

CLOCKS_PER_SEC 1000000

CPU time usage resolutio看起来0.010000 seconds

gettimeofday 已更改9634 uSCPU 时间已更改0.010000

gettimeofday 分辨率看起来是 1 us

#include <stdio.h>
#include <unistd.h>
#include <sys/time.h>
#include <ctime>


int main(int argc, char** argv) {

    struct  timeval now; // wall clock times
    struct  timeval later;

    clock_t tNow = clock(); // clock measures CPU time of this Linux thread
    gettimeofday(&now, NULL); // wall clock time when CPU time first read

    clock_t tLater = tNow;
    while (tNow == tLater)
           tLater = clock(); // consume CPU time

    gettimeofday(&later, NULL); // wall clock time when CPU time has ticked

    printf("CLOCKS_PER_SEC %ld
",CLOCKS_PER_SEC);

    double cpuRes = (double)(tLater - tNow)/CLOCKS_PER_SEC;

    printf("CPU time usage resolution looks to be %f seconds
", cpuRes);

    unsigned long long nowUs = ((unsigned long long)now.tv_sec) * 1000000ULL;
    nowUs += (unsigned long long)now.tv_usec;

    unsigned long long laterUs = ((unsigned long long)later.tv_sec) * 1000000ULL;
    laterUs += (unsigned long long)later.tv_usec;

    printf("gettimeofday changed by %d uS when CPU time changed by %f seconds
", (int)(laterUs - nowUs), cpuRes);

    // now measure resolution of gettimeofday

    gettimeofday(&now, NULL);
    later = now;

    while ((now.tv_sec  == later.tv_sec) && (now.tv_usec == later.tv_usec))
            gettimeofday(&later, NULL);

    nowUs = ((unsigned long long)now.tv_sec) * 1000000ULL;
    nowUs += (unsigned long long)now.tv_usec;

    laterUs = ((unsigned long long)later.tv_sec) * 1000000ULL;
    laterUs += (unsigned long long)later.tv_usec;

    printf("gettimeofday resolution looks to be %d us
", (int)(laterUs - nowUs));

}

解决方案 7:

我在使用 C++ 和 g++ 编译器的 Red Hat Linux 上尝试使用向量计算通用类和非通用类之间的差异时遇到了同样的问题。似乎如果您的程序运行速度比单个时钟慢,则 clock() 读数将始终为零 (0)。

此代码将始终返回 0

#include <iostream>
#include <ctime>

using namespace std;

int main() {

    cout << clock() << endl;

    return 0;
}

当我添加一个索引高达一千万的 for 循环来减慢程序速度时,我得到了一个数字 20000 作为 clock() 的结果

#include <iostream>
#include <ctime>

using namespace std;

int main() {

    for (int i = 0; i < 10000000; i++) {}
    cout << clock() << endl;

    return 0;
}

当然,根据您的盒子的统计数据,结果会有所不同,我正在使用多处理器 Xeon CPU 以及大量 RAM 运行此代码。

相关推荐
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   681  
  在项目管理领域,集成产品开发(IPD)流程以其高效、协同的特点,被众多企业视为提升产品竞争力的关键。IPD流程强调跨部门、跨职能的紧密合作,以确保产品从概念到市场各个环节的无缝衔接。然而,实现这一目标并非易事,它需要企业深刻理解并掌握IPD流程中的跨部门协作艺术。本文将深入探讨IPD流程中跨部门协作的三个关键点,旨在为...
IPD项目管理咨询   9  
  掌握IPD流程图:提升团队协作的关键路径在当今快速变化的商业环境中,团队协作的效率与效果直接关系到项目的成功与否。集成产品开发(Integrated Product Development,简称IPD)作为一种先进的研发管理理念,通过跨部门、跨领域的协同工作,能够显著提升产品开发的速度与质量。而IPD流程图,则是这一理...
IPD流程阶段   9  
  IPD流程概述:理解其核心价值与实施背景集成产品开发(Integrated Product Development,简称IPD)是一种先进的产品开发管理理念,它强调跨部门协作、市场导向和快速响应变化的能力。IPD流程不仅关注产品本身的技术创新,更注重将市场、研发、生产、销售等各个环节紧密集成,以实现产品从概念到市场的高...
华为IPD是什么   7  
  在项目管理领域,IPD(Integrated Product Development,集成产品开发)流程以其跨部门协作、高效决策和快速响应市场变化的特点,被众多企业视为提升竞争力的关键。然而,实践IPD流程并非易事,项目管理中的种种错误往往阻碍了其效果的充分发挥。本文旨在深入探讨如何在实施IPD流程时避免这些常见错误,...
IPD框架   7  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用