Page 4 of 6 FirstFirst ... 23456 LastLast
Results 31 to 40 of 52

Thread: Gettickcount and the rest...

  1. #31

    Gettickcount and the rest...

    Last question on this topic for me thankgod

    Around the place I see people using Sleep(1) in their loops to cut down on cpu.

    Is this appropriate for game use and also do any of you use soemthing superior?

  2. #32

    Gettickcount and the rest...

    Quote Originally Posted by seiferalmasy
    Last question on this topic for me thankgod

    Around the place I see people using Sleep(1) in their loops to cut down on cpu.

    Is this appropriate for game use and also do any of you use soemthing superior?
    No, Sleep(1) is not proper if you are writing a multithreaded application. If your in single thread mode, then it still is not proper, but is used quite frequently.

    A good article to learn from: http://eonclash.com/Tutorials/Multit...ey1.1/ToC.html
    I didn't write it, but since Martin Harvey's website is gone now, I've posted it so that others can get to it. Hopefully we see a new site jump up for Martins work.

  3. #33

    Gettickcount and the rest...

    hmm well being an almost complte novice, would you say that my normal delphix app is multithreaded?
    and I have heard it is better to use threads in games...how does one go about this? Any tutorial?

  4. #34

    Gettickcount and the rest...

    In games, yes, typically you are multithreaded. DelphiX hides some of the threading for you (depending upon the version your using). Reading the tutorial that I posted above will help out. Its written from start to finish for people new to threading and has stuff in it for those used to doing threaded development.

  5. #35

    Gettickcount and the rest...

    Quote Originally Posted by jdarling
    No, Sleep(1) is not proper if you are writing a multithreaded application. If your in single thread mode, then it still is not proper, but is used quite frequently.
    Can you explain why you think that Sleep(1) is not proper way to cut down on cpu?
    There are only 10 types of people in this world; those who understand binary and those who don't.

  6. #36

    Gettickcount and the rest...

    Quote Originally Posted by Clootie
    Can you explain why you think that Sleep(1) is not proper way to cut down on cpu?
    I don't have a problem with Sleep in general, its peoples lack of understanding of what Sleep actually does, and how to implement it. I'd argue against ever using Sleep(1+).

    I'll admit, that calling sleep inside of a thread is quite common (outside of Real Time stuff). I'll also admit to calling Sleep(0) inside of my game loops to lower CPU head (notice I didn't say Sleep(1)). My problem with sleep isn't in these situations, its in the situation where the developer doesn't understand what is going to come from them doing it. Sleep(0) achieves your lowered CPU by simply telling the system to go ahead and process others, then return to me. Sleep(1) tells the system to wait AT LEAST 1ms.

    First off is that sleep can't be canceld, once called you are forced into the wait. This means that on a slower system where a different down time may be necessary it won't be achieved properly. Utilizing it inside of the main loop of some applications may work just fine it still breaks this area. Sleep is not definitive, calling Sleep(1) inside the loop may allow another heavy weight application (or thread) to take over and hold you out of the loop. Thus a Sleep(1) may come close to a Sleep(2+), not a big deal until you add that up a few thousand times. Sleep(0) doesn't require the test for greater, nor the call to the processor timer, thus has a lower call time.

    The largest problem with using Sleep is that people don't realize that you had it inside of a large loop. Thus they turn around and use it inside of a tight loop and wonder why they get inconsistent results on different systems. Code such as the following pops up:

    Proper - Origional code
    [pascal]begin
    while(true) do
    begin
    // Calculate frame difference
    // Game Code
    sleep(0);
    end;
    end;[/pascal]


    Acceptable - Minor "Tweak" cuz they thought it was right
    [pascal]begin
    while(true) do
    begin
    // Calculate frame difference
    // Game Code
    sleep(1);
    end;
    end;[/pascal]


    Bad Idea - Hmmm... Need more time between frames, this should work
    [pascal]begin
    while(true) do
    begin
    StartFrame := GetTickCount;
    // Game Code
    while GetTickCount-StartFrame < 100 do // Supposidly 10 FPS
    sleep(1);
    end;
    end;[/pascal]

    Yes, vetrans know that this is a horrid idea, we know why, and we know how to fix it. But the novice that looked at our code didn't know it. They saw something similar and thus decided that the code above was a good idea.

    In fact, I've seen tutorials and demos written with "Delay" routines that are bound to ProcessMessages and Sleep. I can write code that achieves the same thing with about 1/2 of the overhead.

    Even Worse (but unfortunately common, but quoted as being a proper delay sequence) - Hey I need a proper dealy routine, this looks right
    [pascal]procedure Delay(dwMilliseconds: Longint);
    var
    iStart, iStop: DWORD;
    begin
    iStart := GetTickCount;
    repeat
    iStop := GetTickCount;
    Application.ProcessMessages;
    Sleep(1);
    until (iStop - iStart) >= dwMilliseconds;
    end;[/pascal]

    Now, moving into the threading department. Utilizing Sleep(1) to "Lower CPU" in a multi-threaded application is nothing more then adding even more overhead on single processor systems, and can remove the reasoning for multiple processors to even be present. For anything more the Sleep(0), try utilizing OS Timer Objects. They exist for Win2k+ and Linux. They are more reliable, and achieve the lowered processor utilization, and they don't impart a cost comparativly speaking.

    In .NET Thread.Sleep is another story (from what my .NET developers tell me). Since its managed, I would immagine that they are correct.

    Implementing a threaded spin lock in Delphi requires you to perform a Sleep(0), at least in Delphi 7 and below, I can't speak to over Delphi 7. Simply put, this is due to Delphi not passing the processor lock's properly in assembly. Read up you can find it.

  7. #37

    Gettickcount and the rest...

    well i am no expert, but during my tests using sleep 1 actually increased the game performance especially on bog-slow computers from something impossibly slow to something reasonable. Even on my machine there is noticble smoothness increase, cpustays at 80-90 with sleep (1). I will keep reading these comments

  8. #38
    Fran
    Guest

    Gettickcount and the rest...

    I've been writing multithreaded apps for quite a bit, and i'm of the opinion that sleep does a fine job of passing control away from a thread, thus allowing others to get to it.

    There is however one major downside to using it. It's very inacurate. Sleep(1) will return 1-15ms later, rarely 1. With nothing else happening on the system, the average on my fast computer is 2-3ms, but as soon as something else is going on, it's 10-15ms.

    Here's some code to try it out, if you feel like it, start another thread that does something and watch the numbers soar:

    Code:
    program Project1;
    
    uses
     windows,sysutils;
    
    procedure go_test;
    var
     start_tick,end_tick,now_tick,switches,avg_ticks&#58;longint;
    begin
     switches&#58;=0;
     start_tick&#58;=gettickcount;
     end_tick&#58;=start_tick+5000;
    
     repeat
      sleep&#40;1&#41;;
      inc&#40;switches&#41;;
      now_tick&#58;=gettickcount;
     until now_tick>=end_tick;
    
     avg_ticks&#58;=&#40;now_tick-start_tick&#41; div switches;
    
     messagebox&#40;0,pchar&#40;'Each 1ms switch took on average '+inttostr&#40;avg_ticks&#41;+'ms'&#41;,'Result',mb_ok&#41;;
    end;
    
    begin
     go_test;
    end.

  9. #39
    Fran
    Guest

    Gettickcount and the rest...

    Quote Originally Posted by Robert Kosek
    Try the QueryPerformanceCounter. In fact, here's an example. It's VERY reliable and accurate down to the trillionths of a second.
    Hum... it's been a while, but i'm pretty sure this high precision timer is equivalent to:

    Code:
    function timer_processor_ticks&#58;int64;assembler;
    asm
     rdtsc
    end;
    That's the internal timestamp of the processor (counter incremented by one every processor tick). That is going to be incredibly accurate on processors that never change speeds, but will be awfully inacurate on processors that do (notebooks, many newer desktop ones that do power conservation).

    If you are running a timed loop, timegettime and gettickcount will likely be your best bet, but you need to account for the possibility that the counters will decrement or jump way ahead once in a blue moon. Sometimes windows realizes it's made a mistake a makes a drastic change to the counters to fix things up.

    It happens very rarely on modern processors, but can still happen with some power events and time adjustments (like winter/summer time thing).

  10. #40

    Gettickcount and the rest...

    Quote Originally Posted by Fran
    It's very inacurate.
    Is it still inaccurate even after calling Timebeginperiod(1) (which i can't thank clootie enough for) at the beginning of your app...i have found it returns exactly 1 - 2 ms afterwards if this is implemented.

Page 4 of 6 FirstFirst ... 23456 LastLast

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •