Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

The other problem with naively measuring the frame duration is that you'll get sub-millisecond-jitter because modern operating systems are neiter "hard realtime" nor "soft realtime", which in turn introduces micro-stutter because your game frames will be timed slightly differently than when your new frame shows up on screen (because of the fixed display refresh rate - unless of course a variable refresh rate is used like G-Sync).

This is also my main pet peeve on the web. You can't measure a precise frame duration (made much worse by Spectre/Meltdown mitigations), but you also can't query the display refresh rate.

In the 80's we took perfectly smooth scrolling and animations for granted, because most 80's home computers and game consoles were proper hard-realtime systems. Counter-intuitively this is harder to achieve on modern PCs that are many thousand times faster.



The last time I implemented a timing loop I came up with an approach that would mitigate jitter and oscillation artifacts occurring due to OS overhead (though not solving the aspect of video refresh itself being misaligned). One of my major assumptions was that I could run the game at higher frequency than refresh and therefore rely on downsampling my output, vs the norm of many higher-end games where the base tick is interpolated up to refresh rate.

1. Derive ideal number of elapsed frames using elapsed time from start divided by framerate.

2. Run updates to "catch up" to ideal frames.

3. Observe "rubberbanding" artifact as game oscillates between too slow and too fast.

4. Add limits to how many catchup frames are allowed per render frame to stop the rubberbanding. Implement a notion of "dropped frames" instead, so that our ideal time accounting has a release valve when too much catchup is needed.

5. Now apply a low-pass filter to the amount of catchup frames over time, e.g. if you have a tick of 120hz but your monitor is at 60hz you are likely to see an occasional high frequency oscillation in how many tick frames are supplied per render frame, like [2,3,2,3,2,3]. Filtering can make this [2,2,2,3,3,3]. (It's been a while since I did this, so I don't recall my exact algorithm)

The end result of this effort is that wall-clock time is obeyed over the long-run(minus dropped frames) but the supplied frames are also able to maintain the same pacing for longer periods, which makes the moment-to-moment experience very predictable, hence smooth.

While I haven't tried it, I think the equivalent thing when interpolating would be to freeze a certain issued delta time pace for some number of frames.


I didn't have "real time" but did have an online (as in 1s/s) animation of telemetry data, and the product was such that "smoother than smooth" just meant we increased the maximum allowed charts until we were just back to "smooth". While adding a little latency helped from moment to moment, over a period of minutes you would see a pattern of stutters that was hard to ignore once you were aware of it.

Ultimately I had to fill the screen as best I could, if the paint happened ahead of the deadline I had to decide on painting ahead on the next couple of frames, or doing cleanup work. There was never enough time for both.


> In the 80's we took perfectly smooth scrolling and animations for granted, because most 80's home computers and game consoles were proper hard-realtime systems.

Proper hard realtime means the software is designed to meet stringent time deadlines. If a deadline is missed then the system has failed.

Soft real time means you tolerate missing one or more deadlines if the system is designed to handle it.

The 80's hardware only ran the game code so there was never any CPU contention. There was no kernel, scheduler, threads or processes. The programmers could wrap their heads round the simpler hardware and use all available tricks to optimize every clock tick to do useful work.

Nowadays we have stupid cheap multicore GHz CPU's for a few dollars with GB of RAM so you brute force your way through everything on a general purpose OS like Linux.


Yes, and also the video and audio chips were "cycle-synchronized" with the CPU (e.g. it was guaranteed that a fixed number of CPU cycles after the vsync interrupt you'd always end up at the exact same video raster position etc...).

OTH making the hardware components "asynchronous" and the timings "unpredictable" enabled today's performance (e.g. by introducing caches and pipelines).


> This is also my main pet peeve on the web. You can't measure a precise frame duration (made much worse by Spectre/Meltdown mitigations), but you also can't query the display refresh rate.

Vulkan has extensions for measuring frame timings. I suspect DirectX 12 does too, given how similar it is to Vulkan.

See: https://www.khronos.org/registry/vulkan/specs/1.2-extensions...


I believe Unity has just recently (I.e. since October 2020) taken steps to help mitigate this microstutter, unless I am misunderstanding you.

https://blog.unity.com/technology/fixing-time-deltatime-in-u...


What's preventing PC's from having some realtime clock hardware component that could be used by software?


This isn't the problem, those timers exist and are accessible (unless you're in a web browser). The problem is that your code is essentially running at an unpredictable point in time within the current frame. E.g. if you measure the time duration between the same line of code at the start of your per-frame function you'll get a tiny jitter and never exactly 16.66667 ms (assuming a 60Hz display). I'm not sure what's the exact reason, but I guess there are many things that can throw off this sort of time measurement in a modern operating system (for instance process/thread scheduling).


Modern CPU's already have several counters for 'nominal' cycles (i.e. cycles at a constant frequency). e.g. TSC instructions and Performance-Monitoring Counters.

Converting nominal cycles to time can be unreliable in some cases but not impossible.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: