C 时间测量看起来太慢了

C++ time measurement looks too slow

本文关键字:看起来 时间 测量      更新时间:2023-10-16

我正在使用OpenGL Glut代码编程游戏,并且我正在应用一种游戏开发技术,该技术包括测量游戏主循环的每次迭代的时间,因此您可以使用它要按比例更新游戏场景,直到上次更新。为了实现这一目标,我在循环的开头:

void logicLoop () {
    float finalTime = (float) clock() / CLOCKS_PER_SEC;
    float deltaTime = finalTime - initialTime;
    initialTime = finalTime;
    ...
    // Here I move things using deltaTime value
    ...
}

当我在游戏中添加子弹时,问题出现了。如果子弹不在两秒钟内击中任何目标,则必须将其销毁。然后,我所做的是要参考子弹的创建那一刻:

class Bullet: public GameObject {
    float birthday;
public:
    Bullet () {
        ...
        // Some initialization staff
        ...
        birthday = (float) clock() / CLOCKS_PER_SEC;
    }
    float getBirthday () { return birthday; }
}

,然后我将其添加到逻辑中,直到最后一个时间和三级测量:

if (bullet != NULL) {
    if (finalTime - bullet->getBirthday() > 2) {
        world.remove(bullet);
        bullet = NULL;
    }
}

看起来不错,但是当我运行代码时,子弹会保持太多时间。寻找问题,我打印了(fines -bullet-> getbirthday(((的值,我看着它的增加真的很慢,就像它不是几秒钟内测量的时间一样。

问题在哪里?尽管结果将在几秒钟内,因此子弹将在两秒钟内删除。

这是一个常见的错误。clock()不能测量实际时间的通过;它衡量了CPU运行此特定过程时已经经过了多少时间。

其他过程也需要CPU时间,因此两个时钟不相同。每当您的操作系统执行其他过程的代码时,包括"睡觉"时,都不会计入clock()。如果您的程序在具有多个CPU的系统上进行了多线程,则clock()可能"双计数"时间!

人类对OS时间切片没有知识或感知:我们只是感知实际时间的实际传段(称为"墙壁时间"(。最终,您会看到clock()的时间态与墙时间不同。

请勿使用clock()测量墙壁时间!

您想要gettimeofday()clock_gettime()之类的东西。为了减轻人们更改系统时间的影响,我个人建议使用系统的"单调时钟" clock_gettime(),这是一个与墙时同步的时钟,但任意时期不受与计算机时间玩耍的人的影响。设置。(显然,如果需要,请切换到便携式替代方案。(

实际上是在CPReference.com页面上的clock()

上讨论的

std::clock时间可能比壁时钟更快或更慢,具体取决于操作系统给予程序的执行资源。例如,如果CPU由其他过程共享,则std::clock时间可能比壁时钟慢。另一方面,如果当前过程是多线程的,并且有多个执行核心,则std::clock时间可能比壁时钟更快。

当您不确定发生了什么时,请养成阅读所有功能的习惯。

编辑:事实证明,Glut本身具有您可以使用的功能,这可能很方便。glutGet(GLUT_ELAPSED_TIME)为您拨打glutInit()以来,为您提供了经过的墙数量。所以我想这就是您在这里需要的。它的性能可能会稍高,尤其是如果Glut(或OpenGL的其他部分(已经定期要求墙壁时间,并且如果此功能仅查询已经有时间的时间&Hellip&Hellip;从而使您免于不必要的第二个系统调用(要花费(。

如果您在Windows上,则可以使用QueryPerformanceFquermence/QueryPerformanceCounter,可提供相当准确的时间测量。

这是一个例子。

#include <Windows.h>
using namespace std;
int main()
    {
    LARGE_INTEGER freq = {0, 0};
    QueryPerformanceFrequency(&freq);
    LARGE_INTEGER startTime = {0, 0};
    QueryPerformanceCounter(&startTime);
    // STUFF.
    for(size_t i = 0; i < 100; ++i) {
        cout << i << endl;
        }
    LARGE_INTEGER stopTime = {0, 0};
    QueryPerformanceCounter(&stopTime);
    const double ellapsed = ((double)stopTime.QuadPart - (double)startTime.QuadPart) / freq.QuadPart;
    cout << "Ellapsed: " << ellapsed << endl;
    return 0;
    }