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

Author Topic: sf::Clock and SetThreadAffinity  (Read 5872 times)

0 Members and 1 Guest are viewing this topic.

mkalex777

  • Full Member
  • ***
  • Posts: 206
    • View Profile
sf::Clock and SetThreadAffinity
« on: November 18, 2015, 04:44:51 pm »
Oh god, setting it to fullscreen made all of my windows go to my right monitor, and disabled aero theme.
I also didn't even see my game I just saw a hugely zoomed in version of my desktop.

Force closed it and nothing responded for around 10 seconds.

Don't want to do that again.

So yeah still not sure what to do about the stuttering.

Try to not use sf::Clock, it has a bug inside (call to setthreadaffinity), so it may cause lags.

Just use QueryPerformanceCounter instead of sf::Clock.

Also, add setverticalsync call. It should be called together with setframelimit, because there is a bug in SFML. So if you're using vertical sync enabled, then don't forget to call setframelimit(0)
« Last Edit: November 18, 2015, 04:52:50 pm by mkalex777 »

zsbzsb

  • Hero Member
  • *****
  • Posts: 1409
  • Active Maintainer of CSFML/SFML.NET
    • View Profile
    • My little corner...
    • Email
Re: sf::Clock and SetThreadAffinity
« Reply #1 on: November 18, 2015, 04:48:03 pm »
Try to not use sf::Clock, it has a bug inside (call to setthreadaffinity), so it may cause lags

You know what? I am really getting sick of you posting crap like this around the forums. There is no bugs at all with any of the timing classes, and if there is make a proper report instead of making random replies to threads.

Just use QueryPerformanceCounter instead of sf::Clock.

Just... *facepalm* There is so much messed up in your statements I don't even know where to start.
« Last Edit: November 18, 2015, 04:50:03 pm by zsbzsb »
Motion / MotionNET - Complete video / audio playback for SFML / SFML.NET

NetEXT - An SFML.NET Extension Library based on Thor

mkalex777

  • Full Member
  • ***
  • Posts: 206
    • View Profile
Re: sf::Clock and SetThreadAffinity
« Reply #2 on: November 18, 2015, 05:00:45 pm »
Try to not use sf::Clock, it has a bug inside (call to setthreadaffinity), so it may cause lags

You know what? I am really getting sick of you posting crap like this around the forums. There is no bugs at all with any of the timing classes, and if there is make a proper report instead of making random replies to threads.

Just use QueryPerformanceCounter instead of sf::Clock.

Just... *facepalm* There is so much messed up in your statements I don't even know where to start.

sf::Clock uses SetThreadAffinity, so it's the reason why it will cause measurement lags and deadlocks.
Microsoft never uses SetThreadAffinity with QueryPerformanceCounter in their code and there is no recommendations to do so stupid thing.

And it's the reason why I'm talking about this issue.
So, what is your reason for "Just... *facepalm*"?  ;)
« Last Edit: November 18, 2015, 05:09:06 pm by mkalex777 »

zsbzsb

  • Hero Member
  • *****
  • Posts: 1409
  • Active Maintainer of CSFML/SFML.NET
    • View Profile
    • My little corner...
    • Email
Re: sf::Clock and SetThreadAffinity
« Reply #3 on: November 18, 2015, 05:10:56 pm »
Stop using full quotes and as I already said, if you really think there a bug then report it properly instead of randomly posting and polluting people's threads with off topic information. I will not start a discussion here about why stuff is working correctly.
Motion / MotionNET - Complete video / audio playback for SFML / SFML.NET

NetEXT - An SFML.NET Extension Library based on Thor

mkalex777

  • Full Member
  • ***
  • Posts: 206
    • View Profile
Re: sf::Clock and SetThreadAffinity
« Reply #4 on: November 18, 2015, 05:38:39 pm »
if you really think there a bug then report it properly instead of randomly posting and polluting people's threads with off topic information. I will not start a discussion here about why stuff is working correctly.

I found here 2 bugs:
1) If you want to make sure that your code is executed on specified CPU core, call to the SetThreadAffinity is not enough. Because SetThreadAffinity will not switch CPU core immediately. It will still works on the same core at least till the end of current time quantum. So, there is need to add sleep(0) just after SetThreadAffinity to make sure that the next instruction will be executed on specified CPU core.

There is no call to sleep(0) in the ClockImpl::getCurrentTime().

2) Even if you lock the thread to one processor using SetAffinityMask, QPC can run backwards if you're really unlucky and the hardware sucks. Better to just deal with the case of QPC returning bad values. Because it will not add time lag required to thread context switch.

So, using SetAffinityMask will not fix an issue with different QPC values on differen CPU core. But it will add some lag on each call to sf::Clock.

Also, if you're set the thread affinity, you can deadlock yourself, introduce weird timing and performance bugs, and generally cause yourself grief.

mkalex777

  • Full Member
  • ***
  • Posts: 206
    • View Profile
Re: sf::Clock and SetThreadAffinity
« Reply #5 on: November 18, 2015, 05:44:10 pm »
Alright what about the last question in my last post about vsync and setting the frame limit?
Should I just enable both or just one?

you should enable only one, but you also need to setup both values (if you enable one, then set disabled other), because there is a bug in SFML.
The bug is that if vertical sync is enabled, and you didn't call to SetFrameLimit(0), it will cause lags and jitter of frame rate.

This example will cause lags and movements will not be smooth:
SetVeticalSyncEnabled(true);
 

and this one will works good:
SetVeticalSyncEnabled(true);
SetFrameLimit(0);
 

This bug at least reproduced on CSFML 2.3.

Also notice that different dispay has different refresh rate. For example my samsung LCD has 75 Hz refresh rate. So, you need to call SetFrameLimit with exactly physical refresh rate to get smooth movements.
If you call SetFrameLimit(60) for 75 Hz display it will cause jitter movements on the screen.
« Last Edit: November 18, 2015, 05:52:24 pm by mkalex777 »

zsbzsb

  • Hero Member
  • *****
  • Posts: 1409
  • Active Maintainer of CSFML/SFML.NET
    • View Profile
    • My little corner...
    • Email
Re: sf::Clock and SetThreadAffinity
« Reply #6 on: November 18, 2015, 05:53:58 pm »
@mkalex777 Stop posting your crap now, the OP could care less and this is not helping anybody. As I already said MAKE A PROPER BUG REPORT and stop posting here. After how many countless people have been using SFML and these functions for years and not a single person has claimed there is an issue and now you want to make the OP believe there are problems?
« Last Edit: November 18, 2015, 05:55:33 pm by zsbzsb »
Motion / MotionNET - Complete video / audio playback for SFML / SFML.NET

NetEXT - An SFML.NET Extension Library based on Thor

mkalex777

  • Full Member
  • ***
  • Posts: 206
    • View Profile
Re: sf::Clock and SetThreadAffinity
« Reply #7 on: November 18, 2015, 05:56:39 pm »
Wait but the official SFML FAQ says to use sf::Clock.
But yeah I'm not sure if it would make a huge difference or not.

it's because they believe that lags added by SetThreadAffinity is ok. But if you want to eliminate such unpredictable lags and possible deadlock, don't use sf::Clock until they will fix it by remove SetThreadAffinity call.

mkalex777

  • Full Member
  • ***
  • Posts: 206
    • View Profile
Re: sf::Clock and SetThreadAffinity
« Reply #8 on: November 18, 2015, 05:59:01 pm »
After how many countless people have been using SFML and these functions for years and not a single person has claimed there is an issue and now you want to make the OP believe there are problems?

using some code with obvious bugs by many peoples is not indicate that there is no bug  ;)

At least this bug with QPC and using SetThreadAffinity has been discussed by thousands of experienced game developers on forums. It's not just my opinion. It's investigation of many experienced peoples who works on commercial projects.

The best solution to resolve inconsistent values returned by QPC on machine where QPC uses RDTSC is to avoid using QPC from different threads. Another solution is to install patch which will switch QPC to use system timer instead of RDTSC. By the way this problem is not relevant for nowadays CPU. But by using sf::Clock which uses SetThreadAffinity you will add hidden problems into your code.

PS: just visited link from SFML source code (where solution with SetThreadAffinity was taken) and here is a comment from author of this solution:
Thomas Lee: SetThreadAffinityMask is wrong
 

So, even author of this solution has accept that it's wrong solution. But it still not removed from SFML  :)
« Last Edit: November 18, 2015, 06:29:12 pm by mkalex777 »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11028
    • View Profile
    • development blog
    • Email
Re: sf::Clock and SetThreadAffinity
« Reply #9 on: November 18, 2015, 10:33:38 pm »
Please don't hijack threads anymore.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Mario

  • SFML Team
  • Hero Member
  • *****
  • Posts: 879
    • View Profile
Re: sf::Clock and SetThreadAffinity
« Reply #10 on: November 19, 2015, 01:13:20 pm »
sf::Clock uses SetThreadAffinity, so it's the reason why it will cause measurement lags and deadlocks.
Microsoft never uses SetThreadAffinity with QueryPerformanceCounter in their code and there is no recommendations to do so stupid thing.

To quote from MSDN (emphasis mine):
Quote
Windows XP and Windows 2000

QPC is available on Windows XP and Windows 2000 and works well on most systems. However, some hardware systems' BIOS didn't indicate the hardware CPU characteristics correctly (a non-invariant TSC), and some multi-core or multi-processor systems used processors with TSCs that couldn't be synchronized across cores. Systems with flawed firmware that run these versions of Windows might not provide the same QPC reading on different cores if they used the TSC as the basis for QPC.

So they obviously fixed that starting with Windows Vista and/or added a workaround on their own, which is probably also the reason the previous note linked in source is gone. The original text is obviously quoted in this answer on SO[/b]:

Quote
On a multiprocessor computer, it should not matter which processor is called. However, you can get different results on different processors due to bugs in the basic input/output system (BIOS) or the hardware abstraction layer (HAL). To specify processor affinity for a thread, use the SetThreadAffinityMask function.

I'm not really sure, whether this would be the correct change to do, but considering support for Windows XP is running out for most developers, I think this might even be something to look into, i.e. indeed just clamping the value and no longer toying around with thread affinity. I'm not 100% sure, but this might actually be the cause high CPU load on older CPUs with Nvidia's Multithreaded Optimization being enabled (haven't tried to test this though, but sounds to me like it might screw with the scheduler while other threads are rearranged).

So .NET 4 obviously "fixes" this in their code by simply clamping negative values for time differences back to 0 (see SO question linked above). While it's not 100% accurate, you always have to consider timespans being small enough to essentially disappear due to rounding, so I guess I'll indeed just create a PR for this. After all as mkalex777 correctly noted, toying around with thread affinity isn't really accurate and causes its own issues.

Mario

  • SFML Team
  • Hero Member
  • *****
  • Posts: 879
    • View Profile
Re: sf::Clock and SetThreadAffinity
« Reply #11 on: November 19, 2015, 02:46:51 pm »
Did it for you, feel free to comment:

https://github.com/SFML/SFML/pull/1007

But please, if you think there's some problem or something not working, comment on it, provide a way to do it better. Don't just say "xyz is broken" without explaining why or what to change (to what), thanks. :)