Own update thread

Hey @all,



i’m thinking about using my own update thread. The reason for that is the problem that my 3d application is part of a greater project. I now that jme is more a gaming engine at which the cpu and gpu stress doesn’t matter (i know that you spent much time to avoid that :)). I would like to reduce the cpu and gpu stress as much as possible. To say it more clearly i need a possibility to update (poll the update-queue, input system) and render only if i want it. My current implementation provides a great number of modules (all of the filters from jme3 which can manually be enabled/disabled), camera controls, sky modules, scene processor modules and so on. Each module can be updated and returns if the scene has to be rendered or not. For further information about the update loop see the following reimplementation of the Applications update method:



[java]

@Override

public final void update() {

// execute event loop

super.update();



float tpf = timer.getTimePerFrame() * speed;

// check modules and update flag

synchronized (this) {

needsUpdate |= fireOnApplicationUpdate() | continuousUpdate;

getContext().setAutoFlushFrames(needsUpdate);

if (needsUpdate) {

simpleUpdate(tpf);

stateManager.render(renderManager);

if (context.isRenderable()) {

renderManager.render(tpf);

}

simpleRender();

stateManager.postRender();

notifyAll();

needsUpdate = false;

}

}

}[/java]



That implementation makes me possible to render only if i want. Well ok rendering can be handled but the updates are fired all the time. I think it’s a bit of a problem, because avoiding that SystemListener stuff will also lead on to not updating the input system. Except for the input system and the water i never need a continuous update.



Any ideas what i can do or if there is a chance anyway?



Moe

If you use a own application subclass you are probably able to update the input seperatly of the rest as well. At least I assume that this is possible.

You cannot avoid updating the input system, or more specifically, you don’t gain any performance by doing so since every frame its done on the native side automatically. Not calling MouseInput/KeyInput/etc will not improve speed.



If you want to pause rendering, you should use context.setAutoFlushFrames(false), and then don’t call renderManager.render(). This will put the context into “stand by” mode where it won’t render and in general update less often.

Well, that’s a problem i think. I wanna implement a core application which does the following:


  1. using a canvas and the common awt mouse inputs (MouseListener, MouseMotionListener, MouseWheelListener) for the canvas
  2. not using the jme3 input and audio system
  3. only update and render if i need it (camera moved, settings changed, and so on) in my own update thread
  4. no cpu stress if nothing happens (i also mean not updating all the time)



    In jme2 i’ve implemented such a handling. Will there be a possibility to do so in jme3?
oOMoeOo said:
1. using a canvas and the common awt mouse inputs (MouseListener, MouseMotionListener, MouseWheelListener) for the canvas

You cannot do this, when LWJGL is bound to the canvas, it consumes all input events from the operating system, they will not be passed to Java/AWT.

oOMoeOo said:
2. not using the jme3 input and audio system

You can disable input and audio in jME3, but generally this won't give you anything.

oOMoeOo said:
3. only update and render if i need it (camera moved, settings changed, and so on) in my own update thread
4. no cpu stress if nothing happens (i also mean not updating all the time)

jME3 creates its own update thread for you. You can use context.setAutoFlushFrames() to control which frames should render and which should not (as I mentioned above). Under no circumstances should you block the update thread completely as it handles OS event messages, you should reduce the update rate instead (which in fact setAutoFlushFrames already does)

Yes i know that. And how did you implement it in JMP? Is the update thread running all the time?

Yes, the update loop in jMP is running all the time.

Ok thanks. I experimented a little bit and noticed that setAutoFlushFrames(false) will do the performance boost i wanted. If i’m right, the render thread (LwjglAbstractDisplay) will sleep 50 time millis if the autoFlush is set to false. Could you maybe implement a method to set the sleeptime manually? It’s a really sensitive parameter, so a too high value will lead on to judder. Found out, that setting it to 10 or 20 will solve that problem.



[java]protected void runLoop(){

if (!created.get())

throw new IllegalStateException();



listener.update();



if (renderable.get()){

assert checkGLError();



// calls swap buffers, etc.

try {

if (autoFlush){

Display.update();

}else{

Display.processMessages();

Thread.sleep(50);

// add a small wait

// to reduce CPU usage

}

} catch (Throwable ex){

listener.handleError(“Error while swapping buffers”, ex);

}

}



if (frameRate > 0)

Display.sync(frameRate);



if (renderable.get() && autoFlush)

renderer.onFrame();

}[/java]



In addition i think that the same (setting the sleep time) could be useful for the NullContextRenderer. In my opinion there the following lines are problematic:



[java]while (gapTo > timeNow + savedTimeLate) {

Thread.sleep(1);

timeNow = timer.getTime();

}[/java]



If the NullContext is created and the canvas is hidden the cpu has 50% stress (Core i5, 4 cores, 8 with Hyperthreading). Is there a possibility to change that issue?

For the NullContext, you will set the framerate parameter on the AppSettings to control how often it runs per second.

Yes i know and i set the framerate to 60, but sleeping just 1 milli (like in the example from the NullContext above) will always cause much cpu stress.

I think it’s potentially artificial stress. The sleep yields, so if something else needed the CPU then it would get it.



This fools a CPU usage monitor into thinking that you are cooking your CPU when it’s really just that there’s a thread doing nearly nothing that’s running at a higher priority than the CPU monitor’s ‘nearly nothing’.



The loop could probably be nicer by picking a sleep closer to the time remaining in the “gap”… but it only really makes a difference in what the CPU monitor says… probably not in actual processing.

The issue with sleep is that it is not exactly accurate.

If for example you request to sleep for 20 milliseconds, the actual number could be higher. When you require your application to have an exact framerate like 60 fps, the only way to get the desired accuracy is by sleeping in small amounts until the required amount of time has passed.

ScheduledThreadPoolExecutor has a pretty accurate timer :stuck_out_tongue:

From my research, ScheduledThreadPoolExecutor and Thread.sleep end up using the same mechanism on the OS side to execute the wait operation.

Yeah i know that calling sleep will only suspend the current thread and enqueue it at the back of the thread queue of the os. It’ll never be exactly accurate. But i’ve made the experience, that reducing the sleep rate will smoothing the rendering progress by use of the implementation shown in my first post.

Momoko_Fan said:
From my research, ScheduledThreadPoolExecutor and Thread.sleep end up using the same mechanism on the OS side to execute the wait operation.

Bad research.

Object.wait() and Thread.sleep() use milliseconds:
[java]
Causes the current thread to wait until another thread invokes the notify() method or the notifyAll() method for this object, or some other thread interrupts the current thread, or a certain amount of real time has elapsed.
This method is similar to the wait method of one argument, but it allows finer control over the amount of time to wait for a notification before giving up. The amount of real time, measured in nanoseconds, is given by:
1000000*timeout+nanos
[/java]

ScheduledThreadPool uses nanoTime:
[java]
final long now() {
return System.nanoTime();
}
[/java]

But yeah, they both should use nanoTime to count the time at least.. Still, if you can specify nanos the timing will be more accurate.

Thread.sleep() is native code. The thread pool stuff ultimately falls to Unsafe.park() which is a sun.* class if I recall. park() is supposed to be more responsive (and yes, uses nanos)… but I haven’t looked at the native side of Thread.sleep()… maybe it’s also doing a park() with millis converted to nanos internally or the equivalent. I’d expect Thread.sleep() to translate directly to the OS kernel’s sleep primitive… but maybe not.



…but if so, sleep and park are different things. Or they are supposed to be.

Actually Thread.sleep() allows only 10n values for the argument.

For some pc, repeated call of Thread.sleep(1) make system timer faster

But LockSupport.parkNano(1000
1000) do this job well.

So I don’t use Thread.sleep() at all.