C语言 台间基准代码



我想问问你们中的任何人是否熟悉这个功能,如下所示。我想将其移植到Windows平台,但一直失败。我只能通过使用时间而不是时间规范来获得微秒精度。最后,会出现错误:除以零和访问违规异常

unsigned long get_usecs(struct timeval *myts)
{
    if (clock_gettime(myts))
        terminal_error("clock_gettime");
    return (myts->tv_sec * 1000000 + myts->tv_usec);
}
void burn_loops(unsigned long loops)
{
    unsigned long i;
    /*
    * We need some magic here to prevent the compiler from optimising
    * this loop away. Otherwise trying to emulate a fixed cpu load
    * with this loop will not work.
    */
    for (i = 0; i < loops; i++)
        _ReadWriteBarrier();
}
void calibrate_loop()
{
    unsigned long long start_time, loops_per_msec, run_time = 0;
    unsigned long loops;
    struct timeval myts;
    loops_per_msec = 100000;
redo:
    /* Calibrate to within 1% accuracy */
    while (run_time > 1010000 || run_time < 990000) {
        loops = loops_per_msec;
        start_time = get_usecs(&myts);
        burn_loops(loops);
        run_time = get_usecs(&myts) - start_time;
        loops_per_msec = (1000000 * loops_per_msec / run_time ? run_time : loops_per_msec );
    }
    /* Rechecking after a pause increases reproducibility */
    Sleep(1 * 1000);
    loops = loops_per_msec;
    start_time = get_usecs(&myts);
    burn_loops(loops);
    run_time = get_usecs(&myts) - start_time;
    /* Tolerate 5% difference on checking */
    if (run_time > 1050000 || run_time < 950000)
        goto redo;
    loops_per_ms = loops_per_msec;
}

我知道的唯一clock_gettime()函数是 POSIX 指定的函数,该函数的签名与您正在使用的函数不同。 它确实提供纳秒分辨率(尽管它不太可能提供单纳秒精度)。 但是,据我所知,它在Windows上不可用。 Microsoft获取纳秒级时差的答案是使用其专有的"查询性能计数器"(QPC) API。 但是,请暂时将其放在一边,因为我怀疑时钟分辨率不是您的真正问题。

假设您的 get_usecs() 函数成功检索具有微秒分辨率和至少(大约)毫秒精度的时钟时间,这似乎是预期的,您的代码看起来有点奇特。 特别是这个任务...

loops_per_msec = (1000000 * loops_per_msec / run_time
        ? run_time
        : loops_per_msec );

。看起来很不对劲,当格式强调运算符优先级时会更明显,如上所述(*/的优先级高于?:)。 如果您没有得到可测量的正运行时间,它会给你除以零,否则它总是会给你相同的loops_per_msec值,或者run_time,后者甚至没有正确的单位。

我怀疑意图更像这样......

loops_per_msec = ((1000000 * loops_per_msec)
        / (run_time ? run_time : loops_per_msec));

...,但这仍然有一个问题:如果 1000000 个循环不足以消耗至少一微秒(如测量值),那么你将陷入无限循环,loops_per_msec反复设置为 1000000。

这将不太容易受到该特定问题的影响......

loops_per_msec = ((1000000 * loops_per_msec) / (run_time ? run_time : 1));

。这对我来说也更有意义,因为如果测量的运行时间为 0 微秒,那么 1 微秒是比任何其他可能值更好的非零近似值。 请注意,当测量的运行时间为零微秒时,这将非常迅速地扩展您的loops_per_msec(一百万倍)。 你不能在不溢出的情况下做很多次,即使unsigned long long结果是 128 位,如果你得到溢出,那么你将进入无限循环。 另一方面,如果发生溢出,则它表示您尝试估计的loops_per_msec的正确值大得离谱。

这让我得出了我的结论:我怀疑你真正的问题是你的时序计算是错误的或无效的,要么是因为get_usecs()工作不正常,要么是因为burn_loops()的主体被优化了(尽管你努力避免这种情况)。 您的时间测量不需要亚微秒精度。 事实上,你甚至不需要比毫秒更好的精度,只要你的burn_loop()确实与其参数的值成正比。

相关内容

  • 没有找到相关文章

最新更新