Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clock rate changes with speedstep #69

Closed
SystemParadox opened this issue Sep 18, 2015 · 8 comments
Closed

Clock rate changes with speedstep #69

SystemParadox opened this issue Sep 18, 2015 · 8 comments

Comments

@SystemParadox
Copy link

@SystemParadox SystemParadox commented Sep 18, 2015

I am finding that FreePIE's clock rate changes. I think it may be to do with speedstep (processor throttling).

When I first start FreePIE it's at about 60Hz, but after running it for a while it shifts up to 1000Hz. It appears to coincide with my CPU speed changing from 1000GHz to 3000GHz.

Test script:

import time

def updateTime():
    global prevTime
    try:
        prevTime
    except NameError:
        prevTime = 0
    now = time.clock()
    fps = 1 / (now - prevTime)
    diagnostics.watch(prevTime)
    diagnostics.watch(now)
    diagnostics.watch(fps)
    prevTime = now

updateTime()

What rate is FreePIE supposed to run at?

Thanks.

@AndersMalmgren

This comment has been minimized.

Copy link
Owner

@AndersMalmgren AndersMalmgren commented Sep 18, 2015

The default rate is 64hz not including the overhead of the script it self. And you must take into account hat windows is not a real time system.

Timing in FreePIE is not easy, we cant just let the script have all CPU time it can get because then we will throttle that Core and you will run into performance problem. So we have a pattern for timing the script cycle. Default we use the system clock which is at 64hz. You can override this using system.setThreadTiming and system.threadExecutionInterval

We have some different strategies for timing, if you know C# you can check them out here

https://github.com/AndersMalmgren/FreePIE/tree/master/FreePIE.Core/ScriptEngine/ThreadTiming

If you want the most accurate one (If we ignore that Windows is not a real time system and that FreePIE is managed code) you should use TimingTypes.ThreadYieldMicroSeconds. It will however eat more resources than for example TimingTypes.HighresSystemTimer

@AndersMalmgren

This comment has been minimized.

Copy link
Owner

@AndersMalmgren AndersMalmgren commented Sep 18, 2015

Also,

    diagnostics.watch(prevTime)
    diagnostics.watch(now)
    diagnostics.watch(fps)

will real time update UI, this will impact performance (While UI is in focus)

@SystemParadox

This comment has been minimized.

Copy link
Author

@SystemParadox SystemParadox commented Sep 19, 2015

Thanks that's helpful, looks like some of the other timing strategies should solve the problem.

I still don't understand why the timing changes though, even with the default timing strategy. How does it end up at 1000Hz?!

@SystemParadox

This comment has been minimized.

Copy link
Author

@SystemParadox SystemParadox commented Sep 20, 2015

From what I can work out:

  • SystemTimer sleeps for ThreadExecutionInterval milliseconds, without regard for how long the script took
  • ThreadYield repeatedly yields in a spin loop until enough time has passed (I think it takes account of script time but not entirely sure)
  • ThreadYieldMicroSeconds same as above
  • HighresSystemTimer (BeginPeriodSystemTimerStrategy) - I don't understand what this is doing

Is there not just a simple timer that calls Thread.Sleep for the right amount of time, taking into account how much time the script took?

Also, the default ThreadExecutionInterval is 1, which would mean a default rate of 1000Hz. Where does the 64Hz come from? My suspicion at the moment is that this is not really defined properly, and is instead just rate limited by the thread scheduler or something.

@AndersMalmgren

This comment has been minimized.

Copy link
Owner

@AndersMalmgren AndersMalmgren commented Sep 20, 2015

None of the strategies take into account the time taken for the script sadly. Shouldn't be a problem in normal cases though since the overhead in the script should be minimal. The system clock runs at 64hz, so you can't sleep shorter than 16ms (1000/64). Really strange that you get 1000hz, do you have another program that changes the speed of the system clock? That's how the Highres strategy work, it changes the system clock from 64hz to 1000hz

@AndersMalmgren

This comment has been minimized.

Copy link
Owner

@AndersMalmgren AndersMalmgren commented Sep 20, 2015

Sorry, the yield strategies do take into account the time of the script :)

@SystemParadox

This comment has been minimized.

Copy link
Author

@SystemParadox SystemParadox commented Sep 21, 2015

Ok. May I suggest that the default threadExecutionInterval be set to 16 then? That would avoid the confusing behaviour in the case that the clock rate isn't 64Hz for some reason! :)

@AndersMalmgren

This comment has been minimized.

Copy link
Owner

@AndersMalmgren AndersMalmgren commented Sep 21, 2015

Could have side effects on systems that override default clock speeds.
edit: Basicly Thread.Sleep(1) means that you sleep as short time as the OS lets you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
2 participants
You can’t perform that action at this time.