为什么 C clock() 返回 0

2024-11-11 08:27:00
admin
原创
241
摘要:问题描述:我有类似这样的事情: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 运行此代码。

相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   1565  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1354  
  信创国产芯片作为信息技术创新的核心领域,对于推动国家自主可控生态建设具有至关重要的意义。在全球科技竞争日益激烈的背景下,实现信息技术的自主可控,摆脱对国外技术的依赖,已成为保障国家信息安全和产业可持续发展的关键。国产芯片作为信创产业的基石,其发展水平直接影响着整个信创生态的构建与完善。通过不断提升国产芯片的技术实力、产...
国产信创系统   21  
  信创生态建设旨在实现信息技术领域的自主创新和安全可控,涵盖了从硬件到软件的全产业链。随着数字化转型的加速,信创生态建设的重要性日益凸显,它不仅关乎国家的信息安全,更是推动产业升级和经济高质量发展的关键力量。然而,在推进信创生态建设的过程中,面临着诸多复杂且严峻的挑战,需要深入剖析并寻找切实可行的解决方案。技术创新难题技...
信创操作系统   27  
  信创产业作为国家信息技术创新发展的重要领域,对于保障国家信息安全、推动产业升级具有关键意义。而国产芯片作为信创产业的核心基石,其研发进展备受关注。在信创国产芯片的研发征程中,面临着诸多复杂且艰巨的难点,这些难点犹如一道道关卡,阻碍着国产芯片的快速发展。然而,科研人员和相关企业并未退缩,积极探索并提出了一系列切实可行的解...
国产化替代产品目录   28  
热门文章
项目管理软件有哪些?
云禅道AD
禅道项目管理软件

云端的项目管理软件

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

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

内置subversion和git源码管理

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

免费试用