0

我使用 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;

}

普通的

问题

4

1 回答 1

1

可能的原因:

  1. 您的 clock_gettime 没有使用 VDSO 而是一个系统调用 - 如果在 下运行将可见strace,可以在现代内核版本上配置。
  2. 您的线程被抢占(调度程序从 CPU 中取出)。要运行干净的实验,请以实时优先级运行您的应用程序并固定到特定的 CPU 内核。

另外,我会在试验时禁用 CPU 频率缩放。

于 2019-09-02T19:13:47.613 回答