News:

Use the "Forum Search"
It may help you to find anything in the forum ;).

Frame rate?!?

Started by Max-Max, September 28, 2013, 03:34:19 AM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Max-Max

The -fps switch can be set between 5 and 100, but in-game fps can only be set between 10 and 25.
I tested to increase the in-game fps selection to 5 - 100 and tested 100, 50 and 30 and it seems to run well and a lot smoother than I can get on 25 fps.

I get about 51 fps and 40 simloops on a 2560 x 1440 resolution.

Does any one object if we change the in game setting from 10-25 up to 5 - 100, same as the -fps switch?

I would also like to move the fps rate setting to teh Display dialogue, so we can change it in game and not have to go through new game -> new game -> settings -> display to set it and then close all the windows back to see the effect  :o

Without having any knowledge of what exactly idle time and simloops are I guess that idle time is used for GUI operations, such as moving the map. and simloops is how many times the "world" has been running within one frame, correct?

When I set fps target to 60 I can zoom out maximum on a quite large map and move it without any troubles.

Couldn't the fps be adaptive? let the user decide the idle time and then have simutrans to adjust fps depending on zoom and map operations?
- My code doesn't have bugs. It develops random features...

prissi

Per frame simutrans moves all vehicle. Longer stuff (like creating, loading, and routing goods, finding routes) takes place in a simloop. If you increase the fps, then it does NOT depend on map size, but on the number of vehicles how fast you can display. With 8000 buses I get barely 8 fps, while in pause I could get 100 fps on the same map. During simloops all the interaction of the map is done. Low simloops => no response.

The problem is that normal users think higher fps gives better responsivity while on simutrans it rather does the reverse. I.e the game will acelerate and then, for instance when zooming out, it will be unresponsive until it found the framerate it can still handle.

Movement will also not get much smoother for slow moving stuff (everything below 160 km/h), since the smallest unit of movement is two pixels for straight ways. (So feeling smoother is mostly your mind playing tricks on you). For network games the fps is given by the server and cannot be changed at all.

We had in the past people will complained about 10 or 15 fps despite their all so powerful graphic boards. But this is the usual setting on the server since on network games the slowest client computer sets the limit.

Almost nobody did complain on smoothness of display; the only complaint were the two pixel movement which comes with isometric engines.

I would rather remove the fps at all, nowadays.

Ters

I never seem to get past 5 simloops even with as much idle time as frame time.

greenling

Hello all
I do by new games setting the Frame rate from 25 Frames per second to 10 Frames per second ajust.
A Higher Frame rate do slowing down the computer by more than 2000 convoys.
My portable Computer having only a Athlon II Dual core m320 with 2100Mhz.
Opening hours 20:00 - 23:00
(In Night from friday on saturday and saturday on sunday it possibly that i be keep longer in Forum.)
I am The Assistant from Pakfilearcheologist!
Working on a big Problem!

Max-Max

#4
Quote from: prissi on September 28, 2013, 06:54:32 AM
Per frame simutrans moves all vehicle. Longer stuff (like creating, loading, and routing goods, finding routes) takes place in a simloop. If you increase the fps, then it does NOT depend on map size, but on the number of vehicles how fast you can display. With 8000 buses I get barely 8 fps, while in pause I could get 100 fps on the same map. During simloops all the interaction of the map is done. Low simloops => no response.
Thank you for the explanation.

This is what I experience on a map with quite few vehicles (around 500), PAK-set "Pak128"

FPS 5
Frame Time 200ms
Idle 24-25
Simloops 5.1
vehicles are "jumping" more than the 2pixel limitation (I would estimate a 1/2 tile or so).
Gui drag quite jumpy too

FPS 10
Frame Time 100ms
Idle 24-25
Simloops 5.1
vehicles are less "jumpy" hard to say if it is a slow 2pixel movment or 4 or 5 pixels...
GUI drag less jumpy than 5 FPS but still a bit jumpy...

FPS 25
Frame Time 34ms
Idle 24-25
Simloops 5.0
vehicles goes smooth for the most time, they do occasionally stutter once in a while...
GUI drag 100% smooth

FPS 50 (36)
Frame Time 25ms
Idle 24-25
Simloops 5.1
vehicles goes smooth and very seldom stutter...
GUI drag 100% smooth

FPS 100 (44 - 52)
Frame Time 10-25ms
Idle 24-25
Simloops 22 - 39
vehicles goes very smooth, even diagonal. They don't "stutter", but periodical oscillating a little bit in speed...
GUI drag sticks like a glove!

So frame time is just a calculated value of FPS (1/fps)?
FPS is the target rate of what Simutrans actually manage to do?
But what is regulating Idle time, how is it calculated? I do see that if I zoom out as much I can and move the map, Idle time occasionally goes down and the GUI drag stutter a little.
How is Simloops calculated? What exactly means with one Simloop?

Since It seems to be hardware pending on what effect the FPS setting has, what ever is happening, as a user I do see a difference to the better. I think it would be wise not only to keep it, but also to make it more accessible to the user. If it should be called FPS or something else is another question...
- My code doesn't have bugs. It develops random features...

prissi

The simloops are targeted to get about 5 per second. Getting much higher values means you broke something. Most likely the SDL, which has severe problems with times smaller than 20 ms (and does not pause at all but immediately returns). However, I observed this (time for pause is not waited but immediately return) sometimes under windows when there is more than one real core. Maybe a scheduling issue.

Time with 20 simloops is probably running faster than it should. So this is a good example, why fps > 50 should be avoided. If you have a large screen (and turn on water animation) and then at 100 fps zoom out, my computer stutters to a halt (i.e. I cannot move the marked tile) for several seconds. (Actually, after 60 fps the display should get worse, since you have likely an LCD which are nowadays all fixed at 60 Hz refresh). So you would jump a every 2.5 frames (at 100fps).

At very high fps you are most likely using the simple display alogrithm (emergency mode) and which has clipping error just to keep up.

I can only offer you this explanation. And I am 100% convinced, that if fps is available to the use, almost anybody will uses maximum setting and complain.

Max-Max

#6
On my computer it runs very well on high FPS settings and I have no problem with GUI getting stuck, but I'm runing on an 6 core i7 with 12 threads with 32GB RAM so maybe this is why this works better on my system.

I agree that if it is called FPS, but really doesn't do what you expect it to do, then it should be called something else,  not FPS. But I found it to be a good parameter to elaborate with and for me a value >25 works better, so why should I be constrained to 25? Well I can set -fps 50 on the command line, but it is more convenient to see what it does in real time.

If the GUI gets unresponsive on higher FPS I see it more like a design miss. Why isn't the GUI guaranteed a minimum time to not lock up? In fact, depending on various parameters, like how many objects are updated and if the GUI is in a drag operation could balance the time assigned for GUI and game.

If you perform a GUI drag operation, it is logical that this is the users focus and it doesn't matter if everything else slow down a bit (in update).

Can we at least raise it from 25 to 50 then? Maybe someone can come up with a better name than FPS, or just call it "FPS target"?

***By the way, I had water animation turned on, 100ms
- My code doesn't have bugs. It develops random features...

Ters

An odd thing (to me) about Simutrans is that it processes only one event per frame. Or at least it used to. I think someone wrote that he might try to change that.

prissi

The problem is that sleep slower than 5ms on some windows versions do not sleep at all but returns immediately if there are events but pretent to have slept for 5ms. This will just cause unneccessary CPU load and mess up the system to get the maximum frame rate. Since this is a windows error, there is very little you can do but to set the timing to a regime where you rarely get into this condition, i.e. limit fps to 25 (or maybe 30). 50 frames will not give a nice display, since every fifth frame will be shown twice, i.e. the display will stutter despite a higher frame rate.

NB: Movies are still run in 24 frames per second ...


Markohs

The biggest problem is, as Ters pointed, just processing one event per frame. On heavy CPU load, the system responds very bad to user interaction, and gives the impression of being buggy/unresponsive. This can be easily fixed, I think. In my framework experiment I process all events before each frame and it *feels* better, more reponsive, didn't find any drawback in code that discourages that.

About the windows bug, well, you can allways fix that with a active loop after the dr_sleep waiting for dr_time to get the desired value.

I don't think we really need way more than 22 fps, but I'd just aim allways at 30 fps because it's the starndard for games, it makes no sense aiming higher, it's just wasting CPU.

Ters

Quote from: prissi on October 02, 2013, 12:40:04 PM
NB: Movies are still run in 24 frames per second ...

But they have motion blur, which makes it appear smoother. Stop motion animation don't have it, which makes special effects made using it appear jerky.

prissi

How can you build 22 things per second? Even for a server this seems quite sufficient.

Max-Max

I still don't understand why we have to constrain it to 25 when I (and maybe not just me) actually get a better gaming experience with a higher FPS target. The -FPS command line allows up to 100 as it is now anyway... If the FPS was more accessible it would be easier to adjust it to a value that works with your map and number of vehicles.

I would also complain if I set FPS to 100 and then the GUI locks up. But if I set FPS target, it would be more understandable that I will not be guaranteed this FPS in reality and that my system might be on it knees if it is set to high...

Actually, just as Simutrans suggest the number of cities and factories depending on map size, the FPS target could also be suggested to something suitable that works in the most cases (I know it hasn't to do with map size, but a larger map would probably house a larger number of vehicles etc...)

Quote from: prissi on October 02, 2013, 12:40:04 PMNB: Movies are still run in 24 frames per second ...
That is with old standards... HD has 24 - 60 and UHD(4K) have 60 to 120 FPS. BBC is experimenting with 300 FPS...
- My code doesn't have bugs. It develops random features...

prissi

And movie theaters are produced in 24 frames per second, with the exception of IMAX HD  http://en.wikipedia.org/wiki/IMAX So 24 is still the standard for motion picture productions.

kierongreen

I have a fairly slow computer. Variable frame rate might well slow down and make simutrans on my computer just so that someone with a much better computer can think they are getting a better display. Doesn't make sense to me.

Markohs

#15
This is a delicate subject. Some months ago, I noticed this time management was not really working as it should, and it has many problems, I suspect so.

I didn't wanted to say anything until I knew more about that part of the code, and I'm still unsure what the problem is, but certainly simutrans has a very exotic way of scheduling the simulation, handle events, and render frames. I wanted to know more about it (and try to fix this problems) before giving an oppinion, but now that you are on this issue:

* If the target is getting 5 simloops per seconds, not more, in the benchmark you posted  you report 5.1, 22 - 30 values.Tthat should never happen, as it indicates the world is running faster than it should if I'm not wrong. And specifically a setting named "fps" should never increase it, if the CPU is scarce, the only thing that makes sense is simloops going *under* 5
* The algorithm is based on frame time estimations, if you get to let's say 5 fps (can happen), the game will recover very slowly from this frame time downgrade, it makes no sense.
* This non-cpu greedy behaviour we have is linked ( I suspect ) with the problems we have been reported to happen in CPU's that downgrade their clocks on speedstep technology. This is a severe problem because most laptops use those kind of CPU's, on desktops it's more usually a disabled feature. It's a very serious problem, since one can wonder how many people has installed simutrans on his ubuntu laptop for the first time, tried to play and closed the program in frustration of the slow performance.
* This is not very important but the program should detect when the debugger has triggered a breakpoint, and not take that frame time into account.
* the fps should just limit the maximum fps the program, and not have any other side effect, setting fps to 50 and getting 36 or to 100 and getting 53 is pretty weird, there is something that doesn't make sense here imho.
* One thing that makes this even more weird is the fact of only processing one event per frame. This is not desired, since the slower the program => the less events we check => more events are generated waiting to get processed => Events can take seconds to be processed => The game feels buggy and unstable.
* If our various backends have problems with dr_sleep as prissi pointed, we need to fix them.

Ters

That sleep() is unrealiable is well known, and as I've understood it, no game should rely on it. An alternative is simply to measure how much time has passed since last frame, and move game time forward with that amount. Variable length frames is often undesired, so I guess they process an even number of fixed length frames, and perhaps have some variable carrying over the remaining time to the next pass through the game loop.

prissi

Obviously simutrans uses the real passed time for the frame rate. However, things like flush() may take arbitary amount of times, since those may wait for screen update before returning.

And if there is nothing to do, why should simutrans poll CPU power? That is very bad, especially on tablet and other devices. Instead it should sleep(). Internally there is already a provision to keep the sleep time above 5 ms if possible.

You are welcome to improve the system in such a way that is still updates when the screen size or zoom out is greatly increase and comes back quickly. I worked on that part again and again, and the current implementation is close to the best I could get with different backends and modes like fast forward.

In network mode a 100% fixed frame rate is needed and hence the time is carried over. I suspect the running away of some clients which we never really found out yet may be attributed to a wrong time, possibly do to sleep. But then, if the hardware timer is not reliable, what should you rely on?

Ters

Quote from: prissi on October 03, 2013, 10:28:08 AM
In network mode a 100% fixed frame rate is needed and hence the time is carried over. I suspect the running away of some clients which we never really found out yet may be attributed to a wrong time, possibly do to sleep. But then, if the hardware timer is not reliable, what should you rely on?

I had a computer once that every now and then would skip almost a second forward. Or maybe it was just Windows Me, I'll never know.

isidoro

Prissi is right.  Busy waiting is just bad.  It makes the CPU to heat up and prevents other applications from getting enough CPU time.

Busy waiting has some predicament among some game developers, but it is a huge bad mistake, imho.


Markohs

I was thinking more in, let's say we still have 4 ms because we reached the fps limit and we already did step() and sync_step():

- We dr_sleep() 4 ms
- When we return, we check if the next frame is coming, if it's not, we do a active wait, since dr_time returned sooner than expected.

This should work, and will get CPU idle if the remaining time is big enough, but we'll get precise frame timing. getting time is very cheap, all CPU's have a time register, that gives use ms elapsed since the CPU was initialized, we just need to be careful to do it on the same core, since each cpu *might* have a different value. On Windows it's done wih QueryPerformanceCounter macro, on gcc I don't know.

I know you like to yield CPU when you can too, but in order to be rreponsive we need to be able to measure and process time accurately, and some active wait won't hurt anyone, in fact many pthreads locking implementation do a active spin lock for some cycles before yielding CPU, so see if the context switch can be saved, it's a expensive operation, and we need performance, this is a game after all, no a desktop application.

prissi

In this situation we just do like this. The problem arises after a step() when we are sometimes late (since in networkmode a step cannot be interupted for a sync_step like in single player mode). Normally, sync_step()s are called from all over the program in single player mode and hence the timing then is almost exact (within the resolution of the windows clock). The main loop cares about step() and event processing. Only in networkmode the sync_steps are called from interactive().

Getting time but active waiting is neither cheap nor reliable, or we would not have all these troubles. I tried busy wait once by accident. It was really bad. On an Athlonx64 (two cores) it lead to even windows menus not open any more and unresponsive mouse movements even in simutrans because the windows event queue had to throw away event because of too few calls to poll events. (Maybe that was also the case when you set the frame rate too high, but that code was modified since then, imho).

Markohs

Well, looks like it's a event processing issue then. Why not just making karte_t::interactive processing *ALL* events each iteration, and not just one?

I already implemented it, in the other project and only detected problems with the mouse tooltips, each mouse movement can trigger a tooltip, and a cascade of tooltips is displayed, rest works ok.

I'll start with that if you don't mind, after that we can think about the rest of issues.

Markohs

I've done a fast patch to check all events each frame, the game looks a bit more reponsive maybe, specially on lof framerate situations.

I've not detected any errors yet, but I guess there might be some, it also lacks optimizations, because you can capture all mousemove events, and convert them into a single event. I'm not sure why interactive_event is processed *AFTER* the interactive loop. I might have break network mode, I'll have it another look.

Anyway the plan, now that we are taking a look on this, is creating a world_eventmanager_t, where we *MOVE* all event processing code out of karte_t, to make it  a thinner class, imho. I can move this conversation to programmer's corner forum if you want, btw.

https://dl.dropboxusercontent.com/u/30024783/events.patch

Ters

Quote from: Markohs on October 04, 2013, 05:28:15 PM
[...]because you can capture all mousemove events, and convert them into a single event.

Windows actually does this for us. From what I've understood of what I've read lately, it doesn't actually generate mousemove events until the event queue is empty and you ask for more.

Max-Max

Yes this would be a smaller project on its own.

When digging into the GUI I have seen that there isn't really any uniformed structure of how messages are processed. The thought I would have on this is to use a base class receiving the events for a particular window (dialogue), then find the targeted control and dispatch the message to that control. The control have one callback function for each message it can handle. If nothing is defined it just return false (not handled) or do whatever the derivation tells it to do and then return true if the propagation should stop.

In this way there will already be defined functions to fill in for any supported message and the dispatch mechanic is the same for all GUI controls.

But this was only some thoughts regarding GUI and messages...

Regarding mouse move events, I will be needing those later on to detect mouse enter and mouse exit of a GUI control. It would be good if this could be solved somehow without having to process a myriad of mouse move messages...
- My code doesn't have bugs. It develops random features...

Markohs

Quote from: Ters on October 04, 2013, 05:46:00 PM
Windows actually does this for us. From what I've understood of what I've read lately, it doesn't actually generate mousemove events until the event queue is empty and you ask for more.

I see, but anyway we can't really trust that happening on all plattforms. It's not so much to save CPU than, given simutrans was designed do process just one event per frame, if we fetch multiple events on a frame, unexpected things can happen, maybe. But well, looks like fetching more than one has not been a problem so far, coudn't find any uexpected behaviour.

prissi

The only way when fetching more events per time is when there are doubleclicks, and you removed the single click before the second came. Other than that it shoudl not make much of a change as a normal user cannot generate more than one event per frame usually.

Markohs

What are doubleclicks used for in simutrans? I didn't know that we actually had that concept. :)

Dwachs

Double-click in text-input fields will select the complete string.
Parsley, sage, rosemary, and maggikraut.

Fabio

And once we map double clicks, we can as well use them elsewhere in the GUI.

prissi

On tablets I though using click for preview (like dragging with a mouse) and second click to built.

Max-Max

Quote from: Markohs on October 07, 2013, 10:47:38 AM
What are doubleclicks used for in simutrans? I didn't know that we actually had that concept. :)
Double click on a wagon i depot detach all wagons to the end of the train...
- My code doesn't have bugs. It develops random features...