Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Slow Event Polling (Linux x64)  (Read 12404 times)

0 Members and 1 Guest are viewing this topic.

ioCx

  • Newbie
  • *
  • Posts: 5
    • View Profile
Slow Event Polling (Linux x64)
« on: July 18, 2013, 02:37:51 am »
When I run the example programs provided with the SFML source code (notably "window"), SFML slows to a crawl and gets even slower when I give it events by hitting keys or moving my mouse inside the window. The problem disappears when I completely comment out the event handling loop.

I tried following the advice here: http://en.sfml-dev.org/forums/index.php?topic=6079.0
They had a similar problem to mine, but their issue is from two years ago and the solution provided did not work for me now.

I'm running Arch Linux (x86_64) kernel 3.10.1-2.

EDIT: I downgraded my kernel and it looks like it runs fine, except when I use a USB mouse over the window. My laptop's touchpad mouse doesn't seem to affect the event handling speed. I also experience minor slowdown if I hold down a key with setKeyRepeatEnabled(true) or if I move my laptop's touchpad over the window.
« Last Edit: July 18, 2013, 05:58:40 am by ioCx »

zsbzsb

  • Hero Member
  • *****
  • Posts: 1409
  • Active Maintainer of CSFML/SFML.NET
    • View Profile
    • My little corner...
    • Email
Re: Slow Event Polling (Linux x64)
« Reply #1 on: July 18, 2013, 04:26:38 am »
What version of SFML? and where did you get SFML from? If you pulled SFML from the linux repo you might have gotten an old version of SFML. You should try to download the latest version of SFML from github and compile it yourself.
Motion / MotionNET - Complete video / audio playback for SFML / SFML.NET

NetEXT - An SFML.NET Extension Library based on Thor

ioCx

  • Newbie
  • *
  • Posts: 5
    • View Profile
Re: Slow Event Polling (Linux x64)
« Reply #2 on: July 18, 2013, 05:58:16 am »
SFML 2.0. I had the same problem with both the version from the package manager as well as the version I compiled from the source code on the SFML website.

Fake Edit: I just cloned the SFML repository from github and compiled, same issue.

The minor slowdown I've been getting from keyboard events is probably negligable. And the USB mouse issue is probably because the mouse reports at a much higher rate and at a higher dpi than the laptop touchpad which makes it send a million more mouse movement events.

This is the code I've been using to test this out:

#include <SFML/Window.hpp>
#include <cstdio>

void calculate(sf::Time elapsedTime, sf::Time& updateTime, std::size_t& frameCount)
{
    updateTime += elapsedTime;
    frameCount += 1;

    if (updateTime >= sf::seconds(1.0f))
    {
        printf("fps: %d\n dt: %d\n", frameCount, updateTime.asMicroseconds() / frameCount);
        updateTime -= sf::seconds(1.0f);
        frameCount = 0;
    }
}

int main()
{
    // Create the main window
    sf::Window window(sf::VideoMode(640, 480, 32), "SFML Window", sf::Style::Close);
    window.setFramerateLimit(60);
    window.setKeyRepeatEnabled(true);

    std::size_t frameCount = 0;
    sf::Time updateTime = sf::Time::Zero;
    sf::Clock frameClock;

    // Start the game loop
    while (window.isOpen())
    {
        // Process events
        sf::Event event;
        while (window.pollEvent(event))
        {
            // Close window : exit
            if (event.type == sf::Event::Closed)
                window.close();

            // Escape key : exit
            if ((event.type == sf::Event::KeyPressed) && (event.key.code == sf::Keyboard::Escape))
                window.close();
        }

        calculate(frameClock.restart(), updateTime, frameCount);

        // Finally, display the rendered frame on screen
        window.display();
    }

    return EXIT_SUCCESS;
}
 

I think I get an average of 30 frames per second when I just made circles with my mouse on the empty window as opposed to 60 frames per second when idling.

Another thing to note is that I solved my initial issue by downgrading my kernel and switching from a kernel with the ck patchset to a more vanilla kernel (in one step). I guess that might be something to look into also. I was getting idling at 20 frames per second and it would instantly drop down to <5 if I sent any event to the window. I'm aware that I changed two variables there; I'm not completely sure whether it was the new kernel version or the ck-patchset that caused the problem the first time around.
« Last Edit: July 18, 2013, 06:27:46 am by ioCx »

netrick

  • Full Member
  • ***
  • Posts: 174
    • View Profile
Re: Slow Event Polling (Linux x64)
« Reply #3 on: July 24, 2013, 10:02:21 am »
I tested your code and also my code with heavy event processing and I get amazing fps on Lubuntu 13.04 64 bit. It's something wrong in your distro (lib?).

ioCx

  • Newbie
  • *
  • Posts: 5
    • View Profile
Re: Slow Event Polling (Linux x64)
« Reply #4 on: July 26, 2013, 06:07:33 am »
Alright, I updated my kernel back to 3.10.2, and the extreme slowdown returned. I'm not too sure what changed between 3.9.9 and this version but it got much worse. Netrick, what version of the Linux kernel are you using?

Good news is that I made a very silly mistake earlier; I recompiled the library but I kept the sfml libraries from my package manager installed, so when I ran executables, it would use the .so files from that instead of the newly compiled ones. The solution from the link in the OP (http://en.sfml-dev.org/forums/index.php?topic=6079.0) worked. It's a little bit strange that I encountered the same problem as they did even though they used Windows.

I commented out the body of "processJoystickEvents" in SFML/Window/WindowImpl.hpp, recompiled, and linked an example executable to the libraries in the lib folder and everything ran great.

Looking back at that old thread, was there a proper solution for their problem?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Slow Event Polling (Linux x64)
« Reply #5 on: July 26, 2013, 07:48:28 am »
This should be fixed in the current sources, you should try them.
Laurent Gomila - SFML developer

daemon

  • Newbie
  • *
  • Posts: 21
    • View Profile
Re: Slow Event Polling (Linux x64)
« Reply #6 on: July 26, 2013, 04:36:58 pm »
Everything works fine here on my Arch Linux x64 machine. I'm running kernel 3.10.2 and SFML2 from the official repo.

ioCx

  • Newbie
  • *
  • Posts: 5
    • View Profile
Re: Slow Event Polling (Linux x64)
« Reply #7 on: August 02, 2013, 10:34:32 am »
Yeah, I'm still running into the same problem on SFML 2.1.

It looks like the detected "joystick" at /dev/input/js0 is actually an accelerometer. :

cat /proc/bus/input/devices
...
I: Bus=0019 Vendor=0000 Product=0000 Version=0000
N: Name="Acer BMA150 accelerometer"
P: Phys=wmi/input1
S: Sysfs=/devices/virtual/input/input7
U: Uniq=
H: Handlers=event7 js0
B: PROP=0
B: EV=9
B: ABS=7
...

I can't access it:

# cat js0
cat: js0: Operation not permitted
 

I'm not exactly sure what to do from here.

EDIT: So I found a thread somewhere that said I should just rm js0, and it ended up working fine. Before I was just unloading the joydev whenever I was going to work on an sfml project. I don't know, simply removing something from /dev/ just seems wrong to me (not to mention it won't be persistent), if anyone knows of a better solution, let me know.
« Last Edit: August 02, 2013, 10:43:47 am by ioCx »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Slow Event Polling (Linux x64)
« Reply #8 on: August 02, 2013, 10:56:06 am »
It would be interesting to test other input APIs (SDL, Allegro, ...) and see how they react. If one of them behaves correctly, maybe I can find a fix.
Laurent Gomila - SFML developer

ioCx

  • Newbie
  • *
  • Posts: 5
    • View Profile
Re: Slow Event Polling (Linux x64)
« Reply #9 on: August 02, 2013, 11:49:45 am »
Among GLFW, SDL, and SFML, they all seem to detect the correct amount of actual joysticks; with my accelerometer /dev/input/js0, 0 joysticks are reported by all three. When I plug in an actual joystick they all report one joystick. It seems to be just SFML that ends up slowing down when /dev/input/js0 is the accelerometer.

Thanks for your concern.

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Slow Event Polling (Linux x64)
« Reply #10 on: August 02, 2013, 12:08:46 pm »
Strange. If it is not reported as a joystick, nothing should happen, so I don't know what is slowing your app down.

Would you be able to run a profiler, to get more information about which part of the code is taking all the CPU time? Are we even sure that it's the joysticks fault??
Laurent Gomila - SFML developer

Senzaki

  • Newbie
  • *
  • Posts: 48
    • View Profile
Re: Slow Event Polling (Linux x64)
« Reply #11 on: August 26, 2013, 03:03:57 pm »
I have exactly the same issues. Here's what I found :

- Deactivating ButtonMotionMask and PointerMotionMask in WindowImplX11.cpp removes bad performance caused by the motion of the mouse, but also disables MouseMove events. It's still possible to retrieve mouse position thanks to sf::Mouse::getPosition(). A better fix would be to offer the user an option to sync internal mouse event retrieving with display() (thus getting the mouse position with sf::Mouse::getPosition() and putting it into memory so that it can be used later by pollEvent()). This way, only one mouse event would be retrieved per frame. Actually, this is option is granted by many recent STR games : you usually have an option to "reduce mouse latency", which makes the game behave like SFML : less mouse latency, but bad performances on low-end computers with high-resolution mices. (Actually, I think many of these games still limit the amount of mouse events retrieved per frame, since the framerate isn't SO bad.)

- The way joysticks are handled is really an issue. I also have an accelerometer incorporated in my computer, and this is also causing slowdowns. it's because of the way joysticks are detected. Every time pollEvent is called, the list of joysticks is updated, and SFML tries to find if new joysticks were plugged in. This detection is performed updatePluggedList in Linux/JoystickImpl.cpp. When this function tries to know if /dev/input/js0 is plugged in, it calls the syscall "stat" to know if /dev/input/js0, and it actually exists, even if the user doesn't have the rights to open it. Then JoystickImpl::open calls the syscall open("/dev/input/js0") even if it doesn't have the right. And I think this is this syscall that takes time.

- If SDL and Allegro don't have the same issue, it may be because they us XInput instead of using directly the /dev/input files, because XInput KNOWS it cannot use this "joystick" (=internal accelerometer). But I have to read the sources of SDL to be sure they really use XInput.

I think the first thing to do is to let the programmer choose if SFML should try to use Joysticks, because even if joysticks may work fine on many computers, SFML still calls "stat" Joystick::Count time for EVERY pollEvent call on these computers. I think this is bad because it uses the hard drive, which is a slow device (well, i must admit i don't know how "stat" works, maybe it's optimized and it doesn't use the HDD for every call, but still...).
As you said, the best way to solve this may be to look at the way SDL finds joysticks.

Hope this helps, and thank you for having created this amazing library !

EDIT : Appearently, SDL doesn't use XInput to handle joysticks. I'm currently trying to understand how it's done.
« Last Edit: August 26, 2013, 03:33:05 pm by Senzaki »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Slow Event Polling (Linux x64)
« Reply #12 on: August 26, 2013, 03:15:46 pm »
Thanks for the detailed report.

Quote
bad performances on low-end computers with high-resolution mices
This is really annoying. I have to think more about this issue. Limiting the amount of MouseMoved events is not a problem, but:
- adding a dedicated option in the public API would be unclean (since it's a workaround for a technical problem, not a feature)
- implementing it as you describe would be really really inconvenient

Quote
Every time pollEvent is called, the list of joysticks is updated
Quote
SFML still calls "stat" Joystick::Count time for EVERY pollEvent call
This is wrong since SFML 2.1. I use inotify to watch additions/removals in /dev/input; I update the list of joysticks only when I receive such a notification.

Quote
If SDL and Allegro don't have the same issue, it may be because they us XInput instead of using directly the /dev/input files
Last time I checked, SDL (2.0) was using /dev/input; but they may have XInput code too and I don't know which backend is enabled by default.
Laurent Gomila - SFML developer

Senzaki

  • Newbie
  • *
  • Posts: 48
    • View Profile
Re: Slow Event Polling (Linux x64)
« Reply #13 on: August 26, 2013, 03:32:49 pm »
You're right, I looked at the SDL code and it uses /dev/input, but it also uses Udev. But according to this, you had a few problems implementing it. Maybe a quick look at the way SDL works would help ?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Slow Event Polling (Linux x64)
« Reply #14 on: August 26, 2013, 03:43:17 pm »
A already looked at how SDL works, and it's not much different from what I do.

Since the accelerometer is not detected as a joystick by SFML, it should really not have any impact on performances. It would be great if you or someone else with such an internal accelerometer could investigate in this direction, and see what happens exactly in the joystick code for the accelerometer.
Laurent Gomila - SFML developer