Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » TIMING TIMING PLEASE HELP -- FRUSTRATING ME

This thread is locked; no one can reply to it. rss feed Print
 1   2 
TIMING TIMING PLEASE HELP -- FRUSTRATING ME
encore
Member #7,352
June 2006

let me tell my code first ..

four pads will be moving independently , each moving 1 pixel per frame ... i have two players , each of them move 1 pixel per keyboard move.

now i want my limit my pads to move 100 pixels per second and my players move 100 pixels per second ...

when i run the program my pads and my players move extremely fast since i get nearly 7000 fps ....that is pads move 7000 pixels per second and players move the same ...

now i dont want to limit my game to run at 110 fps .. i want my game to run at the maximum possible fps ....

from the forums what i have learned is ... i can use delta timing to achieve this since i need not limit the fps for this purpose ...

let me tell u what i know about delta timing ....
1) set up timer
2) calculate the time it takes to render a single frame
3) now use this time to make your sprite / objects movements in the game using the formula .

all i want to know now is how do i acheive delta timing using allegro timer functions .... a working example will greatly help me ...

thanks
encore

:-/

Richard Phipps
Member #1,632
November 2001
avatar

First of all, it doesn't matter whether your fps is 200 or 2000 because you are limited by the speed your monitor can refresh.

Most monitors probably go between 60-120 fps, so fixing at around 100 fps should be fine. Your normal tv only refreshes at 50 or 60 fps.

Evert
Member #794
November 2000
avatar

Quote:

now i dont want to limit my game to run at 110 fps .. i want my game to run at the maximum possible fps ....

It is pointless to draw at a higher rate than the monitor refresh, you know that right? At that, it's also pointless to redraw more often than you update your logic.
Either way, limiting your logic to run at 100 cycles per second should not limit your framerate (except in the trivial sense that you should not redraw if nothing has changed).

Steve++
Member #1,816
January 2002

If it's pointless to draw at a higher framerate than that of the monitor (which I don't dispute) then we have to wonder why professional games do it.

These are my thoughts:
Games typically do this loop: get inputs, process logic, show results. This happens in one thread (which may use/spawn other threads). The more times the logic loop can execute per second, the less grainy the game logic becomes. We want game logic to be accurate, but we don't want it to be so accurate that it degrades graphical performance. So what does almost every game do? Interleave game logic with display code.

What are the alternatives? Back in the old days of C64 and 2D consoles, programmers could trap a signal that was triggered when a frame has finished on the monitor. For some stupid reason this capability was scrapped long ago on the PC. If we had access to such a signal, then we could write multithreaded games that maintain the visual framerate at the monitor's refresh rate and use all the left over CPU for gameplay. There may be some frame skipping occasionally (depends on PCs specs) because well written games will guarantee an input/logic framerate as well.

When I think about it though, I think by using flip-chains, the thread that flips will wait if the previous page is still being displayed. It's too early in the morning right now to think of how I could use this in a multithreaded alternative to the conventional game loop though.

Back on topic...

Quote:

all i want to know now is how do i acheive delta timing using allegro timer functions ....

Allegro's timers are too grainy in all OSs except DOS. You can use them, but not very accurately. If you're targeting windows only, you can use the high-resolution timers in the winapi. For that, have a look at these articles.

HoHo
Member #4,534
April 2004
avatar

An exellent thread about timing and threads.
http://www.allegro.cc/forums/thread/585140

I think there was something about delta-time and frame limiting too

__________
In theory, there is no difference between theory and practice. But, in practice, there is - Jan L.A. van de Snepscheut
MMORPG's...Many Men Online Role Playing Girls - Radagar
"Is Java REALLY slower? Does STL really bloat your exes? Find out with your friendly host, HoHo, and his benchmarking machine!" - Jakub Wasilewski

Evert
Member #794
November 2000
avatar

Quote:

If it's pointless to draw at a higher framerate than that of the monitor (which I don't dispute) then we have to wonder why professional games do it.

It looks cool to the average person to see that game X runs with 10000 FPS instead of 5000 FPS on their new over-priced graphics card?
;)

Shawn Hargreaves
The Progenitor
April 2000
avatar

Quote:

If it's pointless to draw at a higher framerate than that of the monitor (which I don't dispute) then we have to wonder why professional games do it.

Most don't. At least not the sensible ones.

Some do if they want to have a double use as a performance benchmarking tool, because if they clamp to the screen refresh, that makes them less useful as a way of measuring GPU performance. But I think that's a crazy reason to design a game in a particular way!

Running faster than the monitor can actually hurt percieved smoothness. If your screen runs at 60hz, and your game runs at 60, all is well. But let's say you up the game to 100hz. That should look smoother, right? Not at all.

1: Render and present in 100hz cycle.
2: Notice that the monitor hasn't blanked yet, so start rendering the next frame.
3: Monitor finishes 60hz cycle. But rendering the next frame hasn't completed yet.
4: Wait for rendering to complete.
5: Now the monitor is in the middle of another 60hz cycle.
6: Finally both the game and monitor are back in sync, so you can present the next frame.

End result: far from upping a 60hz refresh to 100hz, the practical effect is you just dropped it to 30hz!

Much better to just stay exactly in sync with your output device.

Christopher Bludau
Member #5,401
January 2005

I wonder if this is true with disabled vsync, too?
Or maybe I´m getting this wrong.

Thomas Fjellstrom
Member #476
June 2000
avatar

Disabling vsync only makes it so the gfx api (X11, DirectX) doesnt FORCE a wait for vsync(). the monitor still has a vsync.

--
Thomas Fjellstrom - [website] - [email] - [Allegro Wiki] - [Allegro TODO]
"If you can't think of a better solution, don't try to make a better solution." -- weapon_S
"The less evidence we have for what we believe is certain, the more violently we defend beliefs against those who don't agree" -- https://twitter.com/neiltyson/status/592870205409353730

Shawn Hargreaves
The Progenitor
April 2000
avatar

It's still true. Disabling vsync avoids the need for the CPU to wait on the graphics card, but you still can't actually get the new image out to the monitor until the electron beam is in the right place to do that.

If I waste a bunch of time rendering an image that the electron beam isn't in the right place to display, that can then hurt my ability to get it a new correct fresh image at the time when it is ready.

It leads to stuttery performance because the images you are rendering don't properly line up with the ones you are displaying.

Practical example:

At 60hz, you could move a sprite by 3cm each frame.

At 90hz, you move it by 2cm. Then you miss a frame (which you rendered but the monitor never actually displayed), the render another which is displayed. You think you moved it twice by 2cm each time, but the user just saw it jump by 4cm.

Alternating 2cm and 4cm jumps looks ugly: much better to just match the monitor and move it by 3cm every 60hz.

Christopher Bludau
Member #5,401
January 2005

Got it. Thanks.
Is it possible to check for the current refresh rate with allegro? Would be cool, so my game could run with the equivalent amount of fps.

Dustin Dettmer
Member #3,935
October 2003
avatar

Steve++ said:

...
When I think about it though, I think by using flip-chains, the thread that flips will wait if the previous page is still being displayed. It's too early in the morning right now to think of how I could use this in a multithreaded alternative to the conventional game loop though.
...

Doesn't triple buffering already solve this problem?

Shawn Hargreaves's Member Number said:

The Progenitor

Whats a progenitor?

Steve++
Member #1,816
January 2002

Use a dictionary :-* .

Quote:

Doesn't triple buffering already solve this problem?

Triple buffering works just like page-flipping, except there's one more page in the flip-chain. The advantage of three pages is that the time taken to render a frame is the running average of the last two frames (or something like that). In other words, if we get an occasional frame that takes longer to render than a standard refresh cycle, there won't be any jitter if the next frame takes less time to render such that the sum of those two times is not greater than two refresh cycles. The more pages we add to the flip chain, the more opportunity there is for smooth display when render times fluctuate all over the place. But the more pages we add, the more lag the player perceives - what they see happened n frames ago, where n is the number of frames in the chain.

Oops - I didn't answer the quote. No, triple buffering doesn't solve this problem. It just has the potential to make the current thread wait, just like I said. Solving the problem of capping the rendering and utilising the CPU for gameplay while waiting is something a little bit more complicated that is achieved with multithreading.

I was just thinking, perhaps another reason why games tend to use the conventional game loop is that if they use a multithreaded approach instead, what are they to do if they have to wait in the game loop? They must busy wait or sleep. If the thread sleeps and the render thread is also asleep, then the process will sleep and be placed on the back of the process queue. This could make a game really jittery, although on consoles that doesn't apply. But for PCs, I wonder if there's a way to make the process sleep only when it needs, yet keep the game responsive.

Edit: Shawn used to be member #2, but that hardly does justice to Allegro's progenitor.

Kitty Cat
Member #2,815
October 2002
avatar

Quote:

No, triple buffering doesn't solve this problem. It just has the potential to make the current thread wait, just like I said.

Only if you already have a whole frame rendered while another is still waiting to be shown (and another is being shown). You don't want to get too far ahead of what the player sees after all, so if you're too fast you're eventually going to have to wait. If you have a frame drawn and the system is waiting for another, when you go to show it, control will return to your code immediately while the card waits for the vsync.

--
"Do not meddle in the affairs of cats, for they are subtle and will pee on your computer." -- Bruce Graham

Richard Phipps
Member #1,632
November 2001
avatar

On consoles and older computers such as the ST & Amiga you have the advantages that not only is the hardware pretty similar for each owner (meaning you can see where a program slows down for everyone), but that you had complete control over the CPU.

The problem with PC's is they all have different hardware specs and that the OS takes control and steals some of your game's cpu time. This makes 100% smooth animation/scrolling nearly impossible as you miss frames due to the OS taking over infrequently or frequently depending on what other programs are running.

It must be great to develop for a console! :)

A J
Member #3,025
December 2002
avatar

console games should be multithreaded as much as PC games, didn't one of those consoles have like a 9 core CPU ?

___________________________
The more you talk, the more AJ is right. - ML

Richard Phipps
Member #1,632
November 2001
avatar

That's not the issue here. The problem is the OS stealing CPU time from the game and causing missed frames or slowdown.

Arthur Kalliokoski
Second in Command
February 2005
avatar

If you only want something to move 100 pixels per second, no matter how much FPS exceeds 100, the objects should still be on the same pixels for 0.01 second right? So why does refreshing help? Make a little demo that fills tiles on the screen every 5 seconds and hit "Print Screen" every second, doesn't make sense does it?

They all watch too much MSNBC... they get ideas.

Dustin Dettmer
Member #3,935
October 2003
avatar

Quote:

Triple buffering works just like page-flipping, except there's one more page in the flip-chain. The advantage of three pages is that the time taken to render a frame is the running average of the last two frames (or something like that). In other words, if we get an occasional frame that takes longer to render than a standard refresh cycle, there won't be any jitter if the next frame takes less time to render such that the sum of those two times is not greater than two refresh cycles. The more pages we add to the flip chain, the more opportunity there is for smooth display when render times fluctuate all over the place. But the more pages we add, the more lag the player perceives - what they see happened n frames ago, where n is the number of frames in the chain.

Hm, maybe I'm using the wrong term.

By triple buffering I mean the technique where you render onto a video bitmap and use request_video_bitmap which returns immediately and swaps the monitor over to the new bitmap on the next vertical retrace. The result is that you're running effectively as fast as writting directly to the screen, don't have to wait for any vsyncs, and everythings completely buffered.

You need 3 buffers for each state the video bitmap can be in:

  1. Displayed on screen

  2. Will be displayed at any moment

  3. For drawing on

You mentioned something earlier about a trick you thought up using a secondary thread and signals to avoid wasting CPU ticks waiting for the GPU. This is a problem that triple buffering is supposed to solve.

Did i interpret your multithreaded rendering trick incorrectly?

Edit:

Quote:

Oops - I didn't answer the quote. No, triple buffering doesn't solve this problem. It just has the potential to make the current thread wait, just like I said. Solving the problem of capping the rendering and utilising the CPU for gameplay while waiting is something a little bit more complicated that is achieved with multithreading.

Hm, re-reading this quote I think I see something I missed. Are you talking about processing continuously instead of per-frame? Basically utilizing the extra CPU cycles of computers that get ahead of their monitor and are waiting for the monitor refresh rate to catch up with them? How do you propose to do that?

Steve++
Member #1,816
January 2002

Quote:

You mentioned something earlier about a trick you thought up using a secondary thread and signals to avoid wasting CPU ticks waiting for the GPU. This is a problem that triple buffering is supposed to solve.

Yes, this is one advantage triple buffering has - we can certainly take advantage of that when we're not multithreading. But if, on average, the frequency of the entire game loop (i.e. loop { gameplay, render }) exceeds the monitor refresh rate, then either the process will sleep (causing jitter) or the game will have to busy wait for the next available buffer (gets the CPU hot for no reason). If, on the other hand, we get a sequence of slow frames, the game will lose a frame and not even know, until of course it checks some external timer - which is not synchronised to the monitor - and makes an estimate that a frame or two has been dropped.

Quote:

That's not the issue here. The problem is the OS stealing CPU time from the game and causing missed frames or slowdown.

The OS won't steal more than it needs, which shouldn't be much if you haven't got other applications running. The issue isn't the OS stealing time, but the game yielding to the OS, which will use the CPU time on something else (or the system idle process) to maximise CPU throughput.

Quote:

Hm, re-reading this quote I think I see something I missed. Are you talking about processing continuously instead of per-frame? Basically utilizing the extra CPU cycles of computers that get ahead of their monitor and are waiting for the monitor refresh rate to catch up with them?

Exactly.

Quote:

How do you propose to do that?

This will happen naturally. By using a rendering thread and a game logic thread, if the rendering is struggling (not hitting the monitor refresh rate very often or at all), then the rendering and logic threads should both get around a 50-50 split of CPU time. Of course, this may vary because the game logic will need to have a critical section - perhaps where the game state is copied to a buffer or maybe the entire body of the loop if the game logic isn't that heavy (it is important to have the smallest possible critical section). If the rendering loop is, on average, running faster than the monitor refresh rate, its thread will sleep and automatically yield to the game logic thread. So the game logic thread must always have something to do. If we use a delta timing approach (i.e. find out how long it was since the last time the gameplay loop executed and move everything based on that), our gameplay loop will always have something to do.

Neil Walker
Member #210
April 2000
avatar

Quote:

Whats a progenitor?

Shawn's contribution to Allegro was the lovely 8-bit pallete based on the atari st ;)

Neil.
MAME Cabinet Blog / AXL LIBRARY (a games framework) / AXL Documentation and Tutorial

wii:0356-1384-6687-2022, kart:3308-4806-6002. XBOX:chucklepie

Dustin Dettmer
Member #3,935
October 2003
avatar

Quote:

This will happen naturally. By using a rendering thread and a game logic thread, if the rendering is struggling (not hitting the monitor refresh rate very often or at all), then the rendering and logic threads should both get around a 50-50 split of CPU time. Of course, this may vary because the game logic will need to have a critical section - perhaps where the game state is copied to a buffer or maybe the entire body of the loop if the game logic isn't that heavy (it is important to have the smallest possible critical section). If the rendering loop is, on average, running faster than the monitor refresh rate, its thread will sleep and automatically yield to the game logic thread. So the game logic thread must always have something to do. If we use a delta timing approach (i.e. find out how long it was since the last time the gameplay loop executed and move everything based on that), our gameplay loop will always have something to do.

Hm, interesting. Sounds like it would have some unforseen weird update glitches though.

It does make sense though.

Steve++
Member #1,816
January 2002

Quote:

Hm, interesting. Sounds like it would have some unforseen weird update glitches though.

Yeah, that could happen. But let's bear in mind that the render logic should only read the game state. Also, if the game logic is interrupted mid-loop to render, any new input from the keyboard/mouse/etc could affect the loop adversely. The way around this is to copy the input state at the beginning of each game logic loop. Also, we would definitely not make the body of the rendering loop a critical section. This could make the gameplay logic deltas jump all over the place. It would have very little benefit, except increasing visual framerates.

Shawn Hargreaves
The Progenitor
April 2000
avatar

I'm not actually convinced that multithreading the game logic and rendering is a good idea in the majority of cases...

Threaded programming is really really hard! Something to be avoided except where absolutely neccessary.

And to make it work right you have to synchronize all accesses to game state (perhaps by double buffering it). This adds a bunch of runtime overhead, in addition to the coding complexity.

Plus thread switches aren't fast. So you're wasting a bunch of time every time the OS has to jump from one to the other.

And finally, most OS thread schedulers run at a fairly coarse time granularity. 5ms is common. For a 60 fps game, that's a big chunk of the frame time potentially wasted before the OS even notices when it ought to switch.

Adding this all up, it seems to me that on a single processor machine, threading is going to hurt more than it helps!

On a dual core machine things are rather different, because you now have true parallelism and no switching overhead. There is still the overhead of synchronizing your data access, and still the huge increase in coding complexity, but this can be worth it if you can get the machine doing two things in parallel.

So I think it really depends what kind of hardware you are targetting. I certainly wouldn't recommend threading for beginners, though, even if they do have dual processor hardware!

Hyperthreaded processors are an interesting corner case. In theory they do have two truly independent simultaneous execution contexts with no switching overhead, so you'd think they'd be similar to dual core hardware, but in practice it can actually hurt more than it helps if you try to run two threads at once! That's because both threads share the same cache, and can easily end up stomping over each other and constantly flushing the working set. Generally hyperthreading seems to be a win if both threads are running the same code on adjacent pieces of data (eg. transforming a vertex buffer or decoding video), but isn't usually worth using for running totally unrelated computations in each thread.

Steve++
Member #1,816
January 2002

Quote:

Threaded programming is really really hard! Something to be avoided except where absolutely neccessary.

I haven't found it hard yet. Sometimes it's a challenge though. I learned to use semaphores and monitors in some simulator that uses C-- (or something like that). It was hard at first, as is anything new, but I got the hang of it quickly. I've played around extensively with java.nio using two threads to overlap the input and output. It was a challenge, but that had nothing to do with threads. Java makes threading easy though. I'll see what C# is like (probably similar).

Quote:

And to make it work right you have to synchronize all accesses to game state (perhaps by double buffering it). This adds a bunch of runtime overhead, in addition to the coding complexity.

This will add either runtime overhead or complexity - not both (the other will have a negligable increase). By that I mean if the gamestate has to be buffered in a critical section, then this adds runtime overhead, but it does not increase complexity (because this is contained in one small critical section; If, on the other hand, gamestate isn't buffered then we potentially need critical sections all over the place, and this certainly will add to complexity, but will save us the copying overhead.

Quote:

Plus thread switches aren't fast. So you're wasting a bunch of time every time the OS has to jump from one to the other.

They're fast enough! It's not like I'll be creating and destroying threads all over the place. These threads will persist throughout the life of the game. I'll do some benchmarks when I get around to it.

Quote:

And finally, most OS thread schedulers run at a fairly coarse time granularity. 5ms is common. For a 60 fps game, that's a big chunk of the frame time potentially wasted before the OS even notices when it ought to switch.

5ms fits nicely inside 16.7ms, but it still is a problem somewhat. This could be countered by the end of the gameplay loop body yielding to the rendering thread depending on an estimate of the need to do so (i.e. a frame skip could result otherwise). This would involve a combination of dynamic benchmarking and possible a user-controlled variable (some sort of slider that controls a bias between gameplay and rendering processing).

Quote:

Adding this all up, it seems to me that on a single processor machine, threading is going to hurt more than it helps!

On a dual core machine things are rather different, because you now have true parallelism and no switching overhead. There is still the overhead of synchronizing your data access, and still the huge increase in coding complexity, but this can be worth it if you can get the machine doing two things in parallel.

Agreed. The ratio of multi-core to single core machines is only going to increase, so I may as well start this multithreaded approach and hopefully I will have it nailed by the time most people have multiple cores. I still don't think single core machines present much of a problem.

Quote:

I certainly wouldn't recommend threading for beginners, though, even if they do have dual processor hardware!

Yeah - I blame RP and Evert (both posted at the same time) for hijacking this thread after the first post.

 1   2 


Go to: