Abnormally high CPU usage using LWJGL2's thread sleeping method

Here’s a snippet of LWJGL2’s thread sleeping from @Riven and @kappaOne:
https://pastebin.com/nb8wKdqy

It provides fantastically stable sleeping between frames. Easily the best-working method for synchronizing to a framerate that I’ve seen written in Java. So to start, thank you both for writing this! But I’m running into an issue with it. On my MacBook, a simple application synchronized using this method causes the CPU usage to be abnormally high. It’s pushing my cpu temps upwards of 62C for having a plain white background rendered with OpenGL:

http://magaimg.net/img/7lpy.png

Both my Render Thread and my Game Logic Thread. They are both synced to 30 fps. As you can see from the profiler, the actual cpu usage of my game is quite neglagible, and almost all stems fro the synchronization.

When used in my 3d rendering engine I get cpu temps of around 65C, which isn’t ideal considering the application is meant to be open for a large amount of time. I don’t want to burn peoples CPU’s up to a crisp! (65C is still a safe temperature, I know, but it is not comfortable for a laptop user)

The original source of that synchronization method was modified by myself. The problem still persists in the original one though; mine only lets it be called statically rather than needing to create an object of the class.

switching back to this method:


try {
	Thread.sleep(1000l/desiredFPS);
} catch (InterruptedException e) {
	//
}

yields a CPU temperature of 46C after running for 10 minutes. A lot cooler than the 65C+ I get with the other method.

Basically because the LWJGL2 sync is a busy loop. Very accurate but… very inefficient.

Cas :slight_smile:

idk… When I simply use his Sync code with:


public static void main(String[] args) {
  while (true)
    sync(30);
}

I get below 1% CPU usage for that process. This is on Windows, though. Maybe Mac OS will resort to busy loop for Thread.sleep() internally when it is called with very small millisecond durations instead of putting the thread on wait.

Also: The VisualVM profiler is kinda useless for measuring actual CPU usage by a method. It will only measure the wallclock time between method entry and method exit. So even a method only containing Thread.sleep(5000L) will show up in your chart as 5 second execution time for one invocation.
Other profilers are way better to actually measure real CPU usage. They can categorize the time into “running”, “waiting”, “blocking”, “waiting for I/O”.