【问题标题】:C program output analysisC程序输出分析
【发布时间】:2017-08-31 10:07:57
【问题描述】:

在 Windows 10 上运行的简单 C 程序。(Visual Studio 2013)

#include <time.h>

void hello(){
    printf("hello world");
}

int _tmain(int argc, _TCHAR* argv[])
{
    clock_t t;
    for (int i = 0; i<50; i++){
        t = clock();
        hello();
        t = clock() - t;
        double time_taken = ((double)t) / CLOCKS_PER_SEC; // in seconds

        printf("hello() took %f ms to execute \n", time_taken * 1000);
    }
    getchar();
    return 0;
}

输出:

hello worldhello() took 0.000000 ms to execute(35times)
hello worldhello() took 17.000000 ms to execute
hello worldhello() took 3.000000 ms to execute
hello worldhello() took 2.000000 ms to execute
hello worldhello() took 0.000000 ms to execute(5 times)
hello worldhello() took 15.000000 ms to execute
hello worldhello() took 0.000000 ms to execute(4 times)
hello worldhello() took 16.000000 ms to execute
hello worldhello() took 0.000000 ms to execute

有些行是 0.000000,有些行是 15.000000-17.000000

这些输出可能与第二次运行的输出不完全相同。但是在第二次/第三次运行中必须有一些包含 0.000000ms 和 15.000000-17.000000ms 的行。

  1. 0 毫秒到 16 毫秒(是进程 CPU 时间吗?)。请你解释一下真正的原因是什么。

  2. 如果我想避免这种变化并获得像 0-1 ms 这样的统一输出,那么我该如何更改我的代码。 (循环运行 50 次,但如果我运行它 100 或 1000 次,则很容易理解时间效应。)

【问题讨论】:

  • How can I get the Windows system time with millisecond resolution? 的可能重复项。 Windows 时间戳和计时器的分辨率为 16 毫秒,除非您使用 timeBeginPeriod(1)。对于时间安排,无论如何你都应该使用QueryPerformanceCounter。如果您使用的是 Windows 8 或更新版本并且需要精确的当前时间,请使用GetSystemTimePreciseAsFileTime
  • 我认为clock() 不是很准确。试试struct/time.h
  • 我希望您的计算机在从 printf() 返回之前正在执行其他家务管理任务。
  • 你的线程不会一直执行。窗口会定期挂起它以给其他线程时间。结果,这个峰值 - 当线程在循环中被中断时。当他不间断地运行时 - 你有 0 毫秒
  • 感谢大家分享您的重要概念和解决方案:)

标签: c winapi


【解决方案1】:

您的代码太短,clock() 没有准确测量执行时间所需的准确度。增加系统开销以执行时钟测量,您会得到随机结果。

要获得更好的测量结果,请在函数上循环 100 万次,然后用时钟除以 100 万次以获得平均执行时间。

对于更复杂的程序,使用代码分析器可能是更好的解决方案(它专门用于函数的细粒度时钟和测量当前函数指令的执行时间,而不是一项简单的任务)

【讨论】:

    【解决方案2】:

    1) 这是由于过程的频率不是恒定的。

    因此,当您通过循环打印时,它直接取决于处理器的频率。

    2) 为避免这种行为,您可以检查时钟值是否正好超过 1 毫秒或 1 秒,以便在此时准确打印。 (无限循环)

    【讨论】:

      【解决方案3】:

      我同意 Jean-François Fabre 和 Benjamin Audet 的观点。

      您可以使用google_benchmark 对某段代码的性能进行基准测试。它将执行一个循环,以考虑运行时间差异。显示平均值和偏差。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-07-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多