【问题标题】:problem with the output in my C program (gives unexpected output)我的 C 程序中的输出问题(给出了意外的输出)
【发布时间】:2021-01-07 15:53:14
【问题描述】:

这个程序有什么问题,它应该计算每个函数调用的经过时间,但令我惊讶的是,经过时间总是零,因为beginend 完全相同。有人对此有解释吗?

这是我得到的输出:

TIMING TEST: 10000000 calls to rand()

   2113   6249  23817  12054   7060   9945  26819
  13831   6820  14149  13035  30858  13924  26467
   4268  11314  28400   5239   4496  27757  21452
  10878  25064   9049   6508  29612  11373  29913
  10234  31769  16167  24553   1875  23992  30606
   2606  19539   2184  14832  27089  27474  23310
, .. , ,

End time: 1610034404
Begin time: 1610034404
Elapsed time: 0
Time for each call:,10f

代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define NCALLS 10000000
#define NCOLS  7
#define NLINES 7

int main(void) {
    int i, val;
    long begin, diff, end;

    begin = time(NULL);
    srand(time(NULL));
    printf("\nTIMING TEST: %d calls to rand()\n\n", NCALLS);
    for (i = 1; i <= NCALLS; ++i) {
        val = rand();
        if (i <= NCOLS * NLINES) {
            printf("%7d", val);
            if (i % NCOLS == 0)
                putchar('\n');
        } else
        if (i == NCOLS * NLINES + 1)
            printf("%7s\n\n", ", .. , ,");
    }
    end = time(NULL);
    diff = end - begin;
    printf("%s%ld\n%s%ld\n%s%ld\n%s%,10f\n\n",
           "End time: ", end,
           "Begin time: ", begin,
           "Elapsed time: ", diff,
           "Time for each call:", (double)diff / NCALLS);
    return 0;
}

【问题讨论】:

  • 是不是因为这个过程只需要几毫秒(改变时间太短了)?
  • time() 返回整秒,你可能想要clock_gettime()gettimeofday() 之类的东西。
  • i &gt; 50 时,你的for 循环实际上什么都不做,一个好的编译器会发现它并在50 号之后优化循环。
  • @AdrianMole 假设它可以确定循环后不使用 PRNG 的状态。这是可能的,但可能性不大。
  • @DavidSchwartz 是的。我尝试了 OP 的代码,但在循环中添加了 sum += val - 它仍然显示零秒。

标签: c error-handling


【解决方案1】:

你可以使用clock()代替time(NULL)

time_t t1 = clock();

// your code

time_t t2 = clock();

printf("%f", (double)(t2 - t1) / CLOCKS_PER_SEC); // you have to divide it to CLOCKS_PER_SEC (1 000 000) if you want time in seconds

time() 以秒为单位,因此如果您的程序不花费 1 秒,您将看不到差异

stackoverflow 中有人已经回答了他们之间的区别time() vs clock()

【讨论】:

  • 请注意,clock 测量处理器时间,而time 测量墙上时间。
  • 您可以介绍您的提案并解释 OP 的观察结果:time() 的分辨率为 1 秒,这对于测量程序执行时间来说太大了。
【解决方案2】:

更改代码只是为了在循环中花费一些随机时间,使用系统调用几次,使用

        struct stat file_stat;
        for( int j = 0; j < rand()%(1000); j+=1) stat(".", &file_stat);

我们使用了一台非常旧的机器(10,000 次循环,而不是您的代码中的 10,000,000 次循环)

toninho@DSK-2009:/mnt/c/Users/toninho/projects/um$ gcc -std=c17 -Wall tlim.c
toninho@DSK-2009:/mnt/c/Users/toninho/projects/um$ ./a.out

TIMING TEST: 10000 calls to rand()

   953019096   822572575   552766679  1101222688   890440097
   348966778  1483436091  1936203136  1060888701   936990601
   524198868   554412390  1109472424    51262334   723194231
   353522463  1808580291   673860068   818332399   350403991
   442567054  1054917195   229398907   420744931   620127925
  1975661852   812007818  1400791797  1471940068  1739247840
  1364643097   529639947  1569398779    20035674    92849903
  1060567289  1126157009  2111376669   324165122   338724259
   719809477   977786583   510114270   981390269  2029486195
  1551025212  1112929616  2091082251  1066603801  1722106156
, .. , ,

End time: 1610044947
Begin time: 1610044942
Elapsed time: 5
Time for each call:500.000000

使用

#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <time.h>

#define NCALLS 10 * 1000 
#define NCOLS 5
#define NLINES 10

int main(void)
{
    int i, val;
    long begin, diff, end;

    begin = time(NULL);
    srand(210701);
    printf("\nTIMING TEST: %d calls to rand()\n\n", NCALLS);
    for (i = 1; i <= NCALLS; ++i)
    {
        val = rand();
        // spend some time
        struct stat file_stat;
        for( int j = 0; j < rand()%(1000); j+=1) stat(".", &file_stat);

        if (i <= NCOLS * NLINES)
        {
            printf("%12d", val);
            if (i % NCOLS == 0)
                putchar('\n');
        }
        else if (i == NCOLS * NLINES + 1)
            printf("%7s\n\n", ", .. , ,");

        //printf("%7d:  ", i);
        //fgetc(stdin);
    };  // for
    end = time(NULL);
    diff = end - begin;
    printf("%s%ld\n%s%ld\n%s%ld\n%s%10f\n\n", // %
           "End time: ", end,
           "Begin time: ", begin,
           "Elapsed time: ", diff,
           "Time for each call:", (double)diff / NCALLS);
    return 0;
}

【讨论】:

  • 您可能希望使用(double)diff / (NCALLS),因为您将 NCALLS 定义为 10 * 1000,否则您将得到一个不正确的答案,即每次通话的平均时间。
猜你喜欢
  • 2016-03-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-15
  • 1970-01-01
  • 2020-02-06
  • 1970-01-01
  • 2020-06-29
相关资源
最近更新 更多