java - 忙碌的等待, sleep 和准确性

标签 java optimization

我现在正在尝试编写简单的渲染器,它将以 60Hz 的频率调用渲染方法并 hibernate 额外的时间来为其他人节省 CPU 周期。

我遇到了一个简单的问题

while(m_Running){
    //start meassuring whole frame time
    t0 = System.nanoTime();

    render();

    //meassure time spent rendering
    t1 = System.nanoTime();

    if(t1<nextRedraw){
        try{
            diff = nextRedraw-t1;
            ms = diff/1000000;
            ns = (int) (diff-(ms*1000000));
            Thread.sleep(ms, ns);
        }catch(InterruptedException e){
            Logger.logWarning("Renderer interrupted!",e);
        }
        //while(System.nanoTime()<nextRedraw);//busy wait alternative
    }

    //meassure time spent sleeping
    t2 = System.nanoTime();
    nextRedraw = t2+m_RedrawTimeout;

    long frameTime = t2-t0;
    long renderTime = t1-t0;
    long sleepTime = t2-t1;
    long fps = 1000000000/frameTime;
}

运行良好,但与预期的 60fps 相去甚远,而是在值之间跳跃

FPS: 63 Frame: 15,7ms   Render: 2,0ms   Sleep: 13,7ms
FPS: 64 Frame: 15,5ms   Render: 2,0ms   Sleep: 13,5ms
FPS: 63 Frame: 15,7ms   Render: 2,1ms   Sleep: 13,5ms
FPS: 59 Frame: 16,7ms   Render: 2,8ms   Sleep: 14,0ms
FPS: 64 Frame: 15,5ms   Render: 2,2ms   Sleep: 13,3ms

当我尝试改用忙等待时,结果更加一致并且更接近我想要的 fps 目标。

FPS: 60 Frame: 16,4ms   Render: 2,0ms   Sleep: 14,5ms
FPS: 60 Frame: 16,4ms   Render: 2,0ms   Sleep: 14,4ms
FPS: 60 Frame: 16,4ms   Render: 2,0ms   Sleep: 14,4ms
FPS: 61 Frame: 16,3ms   Render: 2,4ms   Sleep: 13,8ms
FPS: 61 Frame: 16,3ms   Render: 2,1ms   Sleep: 14,2ms
FPS: 60 Frame: 16,4ms   Render: 2,0ms   Sleep: 14,4ms

不过,我想避免这种情况,因为这是可以理解的 CPU 缺点。我想到了一个想法,让 sleep 时间比必要的少一点,并精确地遍历剩余时间,但这似乎有点笨拙。

我的问题是,编译器是否以某种方式优化了忙等待,或者是否有其他方法可以达到类似的时序?

如有任何帮助,我们将不胜感激。

谨致问候,

沃伊捷赫

注意:我使用了 System.nanoTime();为了使事情更准确,它没有帮助,但我不知道它有任何性能缺陷

注意:我知道 sleep 很不准确,但我没有找到任何其他替代方法

最佳答案

我想,时间上的微小差异可能会加起来更大,您可以通过使 sleep 取决于总时间来轻松避免这种情况。

有点像

long basetime = System.nanoTime();
for (int i=0; m_Running; ++i) {
    ...
    nextRedraw = baseTime + i * m_RedrawTimeout;
}

如果当前 sleep 太短,这应该会使后续 sleep 更短,反之亦然,因此您获得的 FPS 最多仅每秒变化几毫秒(即 < 1%)。


也许没有问题,只是你衡量的是单帧需要多长时间。这个数字略有不同,并没有说明 FPS 速率。

据我所知,Thread.sleep 中的纳秒被完全忽略。

关于java - 忙碌的等待, sleep 和准确性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27305587/

相关文章:

java - Firestore : Clients and invoices, 如何建模

java - 有没有办法为 JOptionPane.showOptionDialog 设置布局?

java - 当 oraclepki、osdt_cert 和 osdt_core 在类路径上时,从 Jav 6 升级到 Java 8 后无法登录 Web 应用程序

opencv - 优化SIMD直方图计算

python - 为什么在 Keras 中 Adam.iterations 总是设置为 0?

mysql - 每个连接的计数 - 优化

java - 启动 DLL 进程不工作

c - 单独使用递归构建最小堆

java - Java 中此代码的替代方案

java - 使用 CSV-JDBC 驱动程序读取没有 header 的 CSV 文件