Hello Guest

expensive input polls

  • 16 Replies
  • 15296 Views
*

Offline Qudus

  • ***
  • 123
expensive input polls
« on: January 19, 2008, 02:00:22 »
In my benchmark (the Q3 flight one) polling keyboard and mouse (each frame) costs me 3% of the resulting 213 FPS. This is quite a lot. And using YourKit to profile the benachmark I found out, that the Keyboard and Mouse are polled again in the Display.update() method.

So it seems, that calling Keyboard.poll() and Mouse.poll() is unnecessary, if Display.update() is used. Is this correct? In my input test (in the other thread here in this forum) I discussed a problem with the input on Windows, which was caused by the poll() method not called by my input system even if Display.update() was called.

So is it correct, that Keyboard.poll() and Mouse.poll() have to be called before querying the input state changes? Or is this unnecessary?

Is there a way to improve the input polling performance?

Marvin

*

Offline Qudus

  • ***
  • 123
Re: expensive input polls
« Reply #1 on: January 19, 2008, 02:20:21 »
From reading Display's source I found out, that I can simply call
Code: [Select]
if ( Display.isVisible() || Display.isDirty() )
{
    Display.swapBuffers();
}
instead of
Code: [Select]
Display.update();
This will result in the input devices not being polled, which I can do, when I need it. My test has become faster now :). And the pollMessages() method is not needed to be called, since it does nothing else than
Code: [Select]
display_impl.update();
which is already done by the isVisible() and isDirty() calls. I suggest to change that in the source, since it just costs performance.

And is it really necessary to call display_impl from within each method. I would like to have methods like isVisible() and isDirty(), that don't call display_impl.update() (maybe an additional boolean parameter), since it costs me 1% for each of these calls. And as far as I understand it, this display_impl.update() method should only be necessary to be called once per frame. Is this correct?

My initial question stays though. Is it possible to do input polling in a cheaper way?

Marvin

*

Offline Qudus

  • ***
  • 123
Re: expensive input polls
« Reply #2 on: January 19, 2008, 02:53:53 »
After further profiling I found out, that polling Keyboard and mouse both internally calls LinuxDisplay.update() multiple times. This should be changed. It is the most important reason for expensive input polls.

I would offer to do this, but since I am not to familiar with LWGJL internals, I would risk to mess things up. Could please somebody of the LWJGL gurus do this? Would be very cool.

Thanks.
Marvin

*

Offline Matzon

  • *****
  • 2242
Re: expensive input polls
« Reply #3 on: January 19, 2008, 09:14:02 »
elias comitted some changes - can you compile and run from SVN ?

*

Offline elias

  • *****
  • 899
    • http://oddlabs.com
Re: expensive input polls
« Reply #4 on: January 19, 2008, 09:15:33 »
Thank you for investigating this issue. I've removed the update()s from the poll() and read() methods, but I'm not sure how to remove the one in Display.update(), without breaking existing LWJGL programs. For example, a program might never call isDirty() or isActive(), making the processMessages() call in Display important. Ideally, a program should:

Code: [Select]
Display.processMessages();
if (Display.isVisible() || Display.isDirty()){
    Display.swapBuffers();
} else {
    try { Thread.sleep(A_WHILE); } catch (InterruptedException e) {}
}

where neither isVisible() nor isDirty() should call processMessages().

 - elias
« Last Edit: January 19, 2008, 10:09:24 by elias »

*

Offline elias

  • *****
  • 899
    • http://oddlabs.com
Re: expensive input polls
« Reply #5 on: January 19, 2008, 09:55:01 »
I also changed Display.update() to only call display_impl.update() once, by replacing isVisible() and isDirty() with display_impl.isVisible() and display_impl.isDirty().

 - elias

*

Offline Qudus

  • ***
  • 123
Re: expensive input polls
« Reply #6 on: January 19, 2008, 13:58:16 »
elias comitted some changes - can you compile and run from SVN ?

Unfortunately not. I pulled the SVN trunk three days ago and tried to make it compilable in eclipse. But it seems, that there are classes (in the generated folder), that need to be generated (by an ant task, I assume). and since I don't have a working ant environment, I cannot compile the source. Would be great, if I could download a nightly build somewhere.

Thank you for investigating this issue.

You're welcome. It is the least I can do to give something back to you making this great library :).

I've removed the update()s from the poll() and read() methods, but I'm not sure how to remove the one in Display.update(), without breaking existing LWJGL programs.

This could be easily done by overloading the Display.update() method with one, that has an additional boolean parameter, that tells, if these sub-updates and polls are to be done.

For example, a program might never call isDirty() or isActive(), making the processMessages() call in Display important. Ideally, a program should:

Code: [Select]
Display.processMessages();
if (Display.isVisible() || Display.isDirty()){
    Display.swapBuffers();
} else {
    try { Thread.sleep(A_WHILE); } catch (InterruptedException e) {}
}

where neither isVisible() nor isDirty() should call processMessages().

Well, simply overload the isVisible() and isDirty() methods, too with this additional boolean. And then simply forward the boolean from Display.update(boolean).

Thanks again.

Marvin

*

Offline Qudus

  • ***
  • 123
Re: expensive input polls
« Reply #7 on: January 21, 2008, 20:05:00 »
I tried the new 1.1.4 release. And this is my result:
Before I can actually poll the input I have to call Display.processMessages(), if I didn't call any other method, that calls display_impl.update() before. This is principally ok. But it leads me to the conclusion, that display_impl.update() works in a too general way. Is there a way to only process the input related messages, since polling input is still very expensive, if it needs a call to processMessages()?

Marvin

*

Offline elias

  • *****
  • 899
    • http://oddlabs.com
Re: expensive input polls
« Reply #8 on: January 21, 2008, 20:17:33 »
Surely you already call processMessages once per loop? There's no way to filter out input related messages from display_impl.update().

 - elias

*

Offline Qudus

  • ***
  • 123
Re: expensive input polls
« Reply #9 on: January 21, 2008, 20:52:35 »
Surely you already call processMessages once per loop? There's no way to filter out input related messages from display_impl.update().

Well, I call it before polling input only. It doesn't seem to be necessary to be called for anything else. Rendering is done without any problems without the call to display_impl.update(). I don't need the isDirty() check and if isVisible() steals me 4% of rendering performance in my testcase (because of the implicit call to display_impl.update(), I don't need/want it neither. This is exactly, why I ask so vehemently ;).

Marvin

*

Offline elias

  • *****
  • 899
    • http://oddlabs.com
Re: expensive input polls
« Reply #10 on: January 21, 2008, 21:04:51 »
You won't get good behaviour if you don't process the messages from the windowing system, so a call to processMessages() is required, at least once in a while.

 - elias

*

Offline Qudus

  • ***
  • 123
Re: expensive input polls
« Reply #11 on: January 21, 2008, 21:35:54 »
You won't get good behaviour if you don't process the messages from the windowing system, so a call to processMessages() is required, at least once in a while.

And polling the window-messages is the expensive part? If this is true, there's definitely a need for the users to poll different things separately to manage, when to poll what.

What would be the expected problems, if window-messages are never polled?
Would it be sufficient to poll the window-messages each (e.g.) 100-th frame?

Marvin

*

Offline elias

  • *****
  • 899
    • http://oddlabs.com
Re: expensive input polls
« Reply #12 on: January 21, 2008, 21:41:20 »
Window messages includes mouse and keyboard messages, so I can't see how you would avoid it. You can filter events when polling to exclude anything else than input events, but I don't think that's the expensive part.

 - elias

*

Offline Qudus

  • ***
  • 123
Re: expensive input polls
« Reply #13 on: January 23, 2008, 22:05:16 »
I tried to get a closer look at the polling methods. But I can't find the implementation of the XPending method. Is it true, that to input methods are all polled? If it is true, can't this be done through a callback? Shouldn't this be much faster?

After I further tuned Xith3D the time part, that is taken for the display_impl.update() call is getting higher. Now it is 6% (of 470 FPS). So this is getting more and more annoying the more I tune my own code.

Marvin

*

Offline Matzon

  • *****
  • 2242
Re: expensive input polls
« Reply #14 on: January 24, 2008, 07:49:32 »
it would be relevant to locate the part of update that is taking a long time. Fwiw, you should poll every time you render a frame. Furthermore I am not sure that you can - or even should - do it using somekind of callback mechanism.