gpt4 book ai didi

c++ - 使用 C++ Chrono 处理更新循环?

转载 作者:可可西里 更新时间:2023-11-01 17:09:06 25 4
gpt4 key购买 nike

我肯定对新的 C++ chrono 库有点迷茫。

这里我有一个更新循环。它运行两个操作:

engine.Update()
engine.Render()

这些都是很长的操作,很难说它们有多长。

因此,我们测量它们花费了多长时间,然后进行一些计算并找出在我们调用渲染之前逐渐调用更新的最佳方法。

为此,我使用了 C++11 的 Chrono 功能。我选择它是因为它听起来很划算:更准确,更依赖于平台。不过,我发现我遇到的问题比现在多。

以下是我的代码,以及我的主要问题。非常需要有关问题或正确操作方法的任何帮助!

我在评论中直接在有问题的行旁边标记了我的问题,我将在下面重申。

头文件:

class MyClass
{
private:
typedef std::chrono::high_resolution_clock Clock;
Clock::time_point mLastEndTime;
milliseconds mDeltaTime;
}

简化的更新循环

// time it took last loop
milliseconds frameTime;
// The highest we'll let that time go. 60 fps = 1/60, and in milliseconds, * 1000
const milliseconds kMaxDeltatime((int)((1.0f / 60.0f) * 1000.0f)); // It's hard to tell, but this seems to come out to some tiny number, not what I expected!
while (true)
{
// How long did the last update take?
frameTime = duration_cast<milliseconds>(Clock::now() - mLastEndTime); // Is this the best way to get the delta time, with a duration cast?
// Mark the last update time
mLastEndTime = Clock::now();

// Don't update everything with the frameTime, keep it below our maximum fps.
while (frameTime.count() > 0) // Is this the best way to measure greater than 0 milliseconds?
{
// Determine the minimum time. Our frametime, or the max delta time?
mDeltaTime = min(frameTime, kMaxDeltatime);

// Update our engine.
engine->Update((long)mDeltaTime.count()); // From here, it's so much easier to deal with code in longs. Is this the best way to shove a long through my code?

// Subtract the delta time out of the total update time
frameTime -= mDeltaTime;
}
engine->Render();
}

主要问题是:我的 mDeltaTime 总是很小。它基本上陷入了几乎无限循环。这是因为 kMaxDeltatime 非常小,但如果我的目标是每秒 60 帧,我计算的毫秒数是否正确?

以下是上面列出的所有问题:

const milliseconds kMaxDeltatime((int)((1.0f / 60.0f) * 1000.0f)); // It's hard to tell, but this seems to come out to some tiny number, not what I expected!

frameTime = duration_cast<milliseconds>(Clock::now() - mLastEndTime); // Is this the best way to get the delta time, with a duration cast?

while (frameTime.count() > 0) // Is this the best way to measure greater than 0 milliseconds?

engine->Update((long)mDeltaTime.count()); // From here, it's so much easier to deal with code in longs. Is this the best way to shove a long through my code?

很抱歉让大家感到困惑。我觉得这个计时库像个白痴。大多数帮助站点或引用资料,甚至直接代码本身在阅读和理解我的应用时都非常困惑。非常欢迎指出我应该如何搜索解决方案或代码!

编辑:Joachim 指出 std::min/max 在几毫秒内工作得很好!更新代码以反射(reflect)更改。

最佳答案

在使用 std::chrono 时,您应该尽可能避免转换持续时间或将持续时间转换为原始整数值。相反,您应该坚持使用自然持续时间并利用持续时间类型提供的类型安全性。

以下是一系列具体建议。对于每条建议,我都会引用您的原始代码行,然后展示我将如何重写这些行。


const milliseconds kMaxDeltatime((int)((1.0f / 60.0f) * 1000.0f)); // It's hard to tell, but this seems to come out to some tiny number, not what I expected!

没有理由使用手动转换常量进行此类计算。相反,您可以这样做:

typedef duration<long,std::ratio<1,60>> sixtieths_of_a_sec;
constexpr auto kMaxDeltatime = sixtieths_of_a_sec{1};

frameTime = duration_cast<milliseconds>(Clock::now() - mLastEndTime); // Is this the best way to get the delta time, with a duration cast?

您可以只保留其原始类型的值:

auto newEndTime = Clock::now();
auto frameTime = newEndTime - mLastEndTime;
mLastEndTime = newEndTime;

while (frameTime.count() > 0) // Is this the best way to measure greater than 0 milliseconds?

改为使用:

while (frameTime > milliseconds(0))

engine->Update((long)mDeltaTime.count()); // From here, it's so much easier to deal with code in longs. Is this the best way to shove a long through my code?

最好编写始终使用 chrono::duration 类型的代码,而不是完全使用通用整数类型,但是如果你真的需要一个通用整数类型(例如,如果你必须将 long 传递给第三方 API)然后您可以执行以下操作:

auto mDeltaTime = ... // some duration type

long milliseconds = std::chrono::duration_cast<std::duration<long,std::milli>>(mDeltaTime).count();
third_party_api(milliseconds);

或者:

auto milliseconds = mDeltaTime/milliseconds(1);

要获得增量,您应该执行以下操作:

typedef std::common_type<decltype(frameTime),decltype(kMaxDeltatime)>::type common_duration;
auto mDeltaTime = std::min<common_duration>(frameTime, kMaxDeltatime);

关于c++ - 使用 C++ Chrono 处理更新循环?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14785533/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com