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

Author Topic: sf::Clock strangler of internets  (Read 4422 times)

0 Members and 1 Guest are viewing this topic.

Voroz

  • Full Member
  • ***
  • Posts: 128
    • View Profile
sf::Clock strangler of internets
« on: November 01, 2015, 01:12:35 pm »
Hi. I've been working on a network game, and after i implemented box2d on the server i noticed i was starting to get lag, so after a while of searching for bugs i tried running broadband test before and after i started the server.
Before i had 97/97 mbit up down, and after i started the server i had about 10-15 mbit down, and 20 up.

I was thinking it was a networking issue, but i commented all my code out until this was left:

#include <SFML/System.hpp>


int main(){
    sf::Clock clock;
    while (1){
        clock.restart();
    }
return 0;
}

This code takes out 80-90% of my internet. clock.getElapsedTime(); also does it. I really need to use the timer for my application though but since it's a network app, it makes it lag.

Anyone else experience the same issue?

edit: Also this will cause the same issue:
int main(){
    while (1){
        sf::Clock clock;
    }
return 0;
}
« Last Edit: November 01, 2015, 01:32:20 pm by Voroz »

mkalex777

  • Full Member
  • ***
  • Posts: 206
    • View Profile
Re: sf::Clock strangler of internets
« Reply #1 on: November 01, 2015, 01:51:42 pm »
Do you run it on windows or linux?
I noticed that sf::Clock sets affinity mask when you call getCurrentTime. Probably it was added to fix hardware malfunction (on some bad hardware it may returns different values on different CPU core).
Actually, the call to SetThreadAffinityMask may cause deadlocks and lags in some cases.
I'm not sure if it's your case but it's better to not using sf::Clock from different threads.
« Last Edit: November 01, 2015, 01:55:43 pm by mkalex777 »

Voroz

  • Full Member
  • ***
  • Posts: 128
    • View Profile
Re: sf::Clock strangler of internets
« Reply #2 on: November 01, 2015, 01:53:02 pm »
Do you run it on windows or linux?
I noticed that sf::Clock sets affinity mask when you call getCurrentTime. So, this is reason why it may cause deadlocks and lags in some cases.
I'm not sure if it's your case but it's better to not using sf::Clock from different threads.
It also happens when restarting the clock though. I use Windows 7, and i only use 1 thread.

edit: I gotta go for a while now so wont reply for a few hours.

mkalex777

  • Full Member
  • ***
  • Posts: 206
    • View Profile
Re: sf::Clock strangler of internets
« Reply #3 on: November 01, 2015, 01:58:42 pm »
Windows implementation uses QueryPerformanceCounter which should not affect network.
But it may be caused by SetThreadAffinityMask or it's just a bug in your tool which is used to measure network performance.

Voroz

  • Full Member
  • ***
  • Posts: 128
    • View Profile
Re: sf::Clock strangler of internets
« Reply #4 on: November 01, 2015, 04:31:39 pm »
It might be a bug in the online tools, but i doubt it because of the network lag i'm getting in my app. If i use local IP i don't get any lag, and online IP worked without lag before i implemented box2d and the timer.

The way box2d runs on the server doesn't change based on your connection stability to the server so i believe the clock actually slows down the internet alot.

I will however try an earlier version of my network application without box2d and implement an sf::Clock to see if it suddenly starts lagging with it.

Voroz

  • Full Member
  • ***
  • Posts: 128
    • View Profile
Re: sf::Clock strangler of internets
« Reply #5 on: November 01, 2015, 04:46:37 pm »
Okay i just tested an older version of the server and client.

Results are that everything worked perfectly, and then i wrote sf::Clock clock; in the beginning of the while loop.
Suddenly i see alot of lag while walking around. The internet tools aren't wrong, sf::Clock actually destroys the internet.

It works fine as long as you have a window and draw something, because that will slow down your app alot, and especially if you run vsync or framelimit, but if you just run a console window and get millions of frames a second, like on a server. Then it's a big problem.

I also don't know how to slow down the application without either using a window and then setFrameLimit, or using the clock, but the clock is the one thing that needs to slow down, so i can't use it for that ^^.

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Re: sf::Clock strangler of internets
« Reply #6 on: November 01, 2015, 04:54:32 pm »
sf::Clock actually destroys the internet.
Quite a daring statement :D

Can you test if the problem appears also with std::chrono::high_resolution_clock (given that you have a really recent compiler, especially if it's MSVC). And although I don't think a profiler would give much more information than just point to the OS call, it's also something you could try.

But how often do you actually need to reset the clock? Why would you do that in a busy-waiting loop? Remember that there's sf::sleep(), even if it's not extemely precise.

And of course, minimal complete example.
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

Voroz

  • Full Member
  • ***
  • Posts: 128
    • View Profile
Re: sf::Clock strangler of internets
« Reply #7 on: November 01, 2015, 05:12:22 pm »
I got this answer on IRC

BlueCobold:
"the clock isn't the problem
the problem is you calling it as often as possible
which needs a kernel-call
so the kernel can't handle all the other stuff it needs to do "

And they also recommended to use sleep to not run the server that often, which seems reasonable. It actually doesn't have to be that precise either. I'll use sleep first and then get the actual time passed after sleep so the box2d simulation runs well.

mkalex777

  • Full Member
  • ***
  • Posts: 206
    • View Profile
Re: sf::Clock strangler of internets
« Reply #8 on: November 02, 2015, 08:19:35 am »
it's bad to call sf::Clock very frequently,as I say before it usese setthread affinity, so it may slowdown your code due to thread context switch lags.

If you need more fast and more precise time measurement, don't use sf::Clock. Just write your own wrapper for QueryPerformanceFrequency

Actually it's a serious bug in SFML that it uses SetThreadAffinity in the Clock. It makes sf::Clock completely useless, because even GetTickCount will works much faster, more predictable and more precise.

But for me it doesn't matter, because I'm using C# and it already has more flexible wrapper for QueryPerformanceCounter (System.Diagnostics.Stopwatch). It doesn't use call to SetThreadAffinity, so it works much faster and more precise.
« Last Edit: November 02, 2015, 09:05:43 am by mkalex777 »

Mario

  • SFML Team
  • Hero Member
  • *****
  • Posts: 879
    • View Profile
Re: sf::Clock strangler of internets
« Reply #9 on: November 02, 2015, 09:05:27 am »
Actually it's a serious bug in SFML that it uses SetThreadAffinity in the Clock. It makes sf::Clock completely useless, because even GetTickCount will works much faster, more predictable and more precise.
That probably will fix this problem, but instead it might reintroduce the other problem sf::Clock tried to fix. Not sure that's a perfect solution.

mkalex777

  • Full Member
  • ***
  • Posts: 206
    • View Profile
Re: sf::Clock strangler of internets
« Reply #10 on: November 02, 2015, 09:09:56 am »
Actually it's a serious bug in SFML that it uses SetThreadAffinity in the Clock. It makes sf::Clock completely useless, because even GetTickCount will works much faster, more predictable and more precise.
That probably will fix this problem, but instead it might reintroduce the other problem sf::Clock tried to fix. Not sure that's a perfect solution.

Actually there is no such problem. It attempts to fix issues caused by invalid BIOS.
I don't think that SFML library should fix bugs in specific bios on specific motherboard.
For example, Stopwatch wrapper doesn't use such kludge. It's implemented by microsoft and works very good on all machines I ever seen.

And even for machine with invalid bios it completely have no sense to add such kluge into library. Most of the time Clock is used from single thread. So, such kludge will affect performance. If you need to fix it for specific hardware, just add SetThreadAffinity before access to sf::Clock. But I have no idea why it placed inside Clock which prevents to use it with no performance issues.

It's some kind of implementing library with printf function which prints hardcoded string "Hello World", so you cannot use it to print other strings. But it helps to write hello world application by using printf without parameters...
« Last Edit: November 02, 2015, 09:19:33 am by mkalex777 »