【发布时间】:2020-01-05 18:25:31
【问题描述】:
我使用 Linux 中的 clock_gettime() 和 Windows 中的 QueryPerformanceCounter() 来测量时间。在测量时间的时候,我遇到了一个有趣的案例。
首先,我在无限循环中计算 DeltaTime。这个循环调用了一些更新函数。为了计算 DeltaTime,程序在 Update 函数中等待 40 毫秒,因为 update 函数是空的。
然后,在编译为 Win64-Debug 的程序中,我测量 DeltaTime。它大约是 0.040f。只要程序正在运行,这种情况就会继续(Win64-Release 也可以这样工作)。它运行正确。
但是在编译为Linux64-Debug或者Linux64-Release的程序中,出现了问题。
程序开始运行时。一切正常。 DeltaTime 约为 0.040f。但过了一会儿,deltatime 计算为 0.12XXf 或 0.132XX,紧随其后是 0.040f。以此类推。
我以为我正确使用了 QueryPerformanceCounter 并错误地使用了 clock_gettime()。然后我决定用标准库std::chrono::high_resolution_clock来试试,但是还是一样的。没有变化。
#define MICROSECONDS (1000*1000)
auto prev_time = std::chrono::high_resolution_clock::now();
decltype(prev_time) current_time;
while(1)
{
current_time = std::chrono::high_resolution_clock::now();
int64_t deltaTime = std::chrono::duration_cast<std::chrono::microseconds>(current_time - previous_time).count();
printf("DeltaTime: %f", deltaTime/(float)MICROSECONDS);
NetworkManager::instance().Update();
prev_time = current_time;
}
void NetworkManager::Update()
{
auto start = std::chrono::high_resolution_clock::now();
decltype(start) end;
while(1)
{
end = std::chrono::high_resolution_clock::now();
int64_t y = std::chrono::duration_cast<std::chrono::microseconds>(end-start).count();
if(y/(float)MICROSECONDS >= 0.040f)
break;
}
return;
}
【问题讨论】:
-
如果你在 strace 下运行你的 linux 可执行文件,它会显示大量的系统调用吗?
-
考虑将
MICROSECONDS定义为float,而不是(float)MICROSECONDS。例如:constexpr float MICROSECONDS = 1000*1000; -
int64_t y = std::chrono::duration_cast<std::chrono::microseconds>(end-start).count();我个人会在那里使用auto代替y。还有(float)MICROSECONDS- eeek,请不要使用 C 风格的强制转换。 -
@bobah 我从未使用过 strace,但我会尝试。
-
不相关:这些图像可以是粘贴文本。尽可能首选文字,因为图像对太多人来说是不透明的。
标签: c++ linux c++11 time-measurement