Page 1 of 2 12 LastLast
Results 1 to 10 of 12

Thread: How to delay without polling?

  1. #1

    How to delay without polling?

    Hello everyone!
    As I am trying to write a small demo, I stumbled on this problem:
    Let's deviate from my demo and go to a simple repeat loop that does write an increasing integer and outputs every one second (using getticount64). If I put sleep or delay for 1 millisec, the perfromance tanks. I am talking about from about 15.000.000 loops to about 1000 loops. The utilization drops from 100% (one thread) to 0%.
    How to do *something* when a specific time passes, without checking on every tick (and thus eating cpu)?
    Last edited by SilverWarior; 13-07-2022 at 08:48 PM. Reason: Reverting last post edit on request of the post author

  2. #2
    Have you tried using the timer? Set interval to 1000 (that is 1000 milliseconds=1 second ) and do your stuff when the onTImer event kicks in..

  3. #3
    can you provide a simple example, without classes (plain pascal)

  4. #4
    I hope this can be of help or inspiration.

    I use the Lazarus flavor of pascal:
    With one form with just one timer and one label (for showing the time) the whole no class quick example looks like this:

    unit Unit1;

    {$mode objfpc}{$H+}

    interface

    uses
    Classes, SysUtils, Forms, Controls, Graphics, Dialogs, ExtCtrls, StdCtrls;

    type

    { TForm1 }

    TForm1 = class(TForm)
    Label1: TLabel;
    Timer1: TTimer;
    procedure FormCreate(Sender: TObject);
    procedure Timer1Timer(Sender: TObject);
    private

    public

    end;

    var
    Form1: TForm1;
    iSeconds: integer;

    implementation

    {$R *.lfm}


    { TForm1 }

    procedure TForm1.Timer1Timer(Sender: TObject);
    begin
    iSeconds := iSeconds + 1;
    label1.Caption := IntToStr(iSeconds) + ' seconds counted.';
    end;

    procedure TForm1.FormCreate(Sender: TObject);
    begin
    iSeconds := 0;
    end;

    end.
    Last edited by Jonax; 11-07-2022 at 08:14 PM. Reason: comment

  5. #5
    Thanks for the reply, but I write simple console programs, with custom ui if needed (when games opengl), and I don't knowabout or use classes and forms. I cannot understand it.

  6. #6
    Sorry I couldn't be of help. I always start with a form when programming in pascal. Hopefully there are other users here with more console experience.

  7. #7
    Quote Originally Posted by nerduke View Post
    How to do *something* when a specific time passes, without checking on every tick (and thus eating cpu)?
    Designing "game update loop" are you?
    Well as you already figured it out polling is not a god approach. In fact pooling is as if someone tasked you to do something every five minutes and then you go and keep constantly checking your watch over and over again to see when five minutes has passed. Not very effective is it.

    Most commonly used approach for this is measuring the time it has taken you to do some work (updating game objects, rendering frame or whatever needs to be done in timed intervals) and then you calculate of how much time you need to sleep in order to reach the start of the next interval.

    For instance lets say you have desired time interval of 1 second. You do some processing in current cycle which takes 236 ms. In order to start the next cycle precisely 1 second after the first cycle was started you calculate how much time you need to sleep after the work in your current cycle was done by simply substracting the time that work took from the desired time interval. In this case this would be 1000 ms (desired time interval) - 236 ms (time it took to do the work) and you get that you need to sleep for 764 ms. If the work would took 481 ms you would need to sleep 1000 ms - 481 ms = 519 ms.

    So pseudocode for your loop would look something like this

    Code:
    repeat
      Record when work started (get current time)
      Do some work
      Calculate how much time elapsed since work started till now
      Calculate how much time you need to sleep by substracting the work time from desired interval
      Sleep for needed time
    unjtil EndLoop is True; //EndLoop is control variable used for terminating the loop
    This way you are doing one loop per interval and thus are not burning CPU processing power for needlessly checking current time all the time. And your loop will be automatically adapting to the amount of workload that needs to be done in each cycle making sure that the code is executed in regular intervals regardless of how much time was needed to complete the work in specific cycle.
    Granted it will fail if the time required to complete work in one cycle was bigger than the desired interval. You surely know this from games as being called lag.

    As for using Delphi Timer for this sort of things. Be aware that since Delphi Timer is message based there is no guarantee that its message will be processed at the right time in order to fire the OnTime event. This means that its precision is far from being precise. How far? Years ago when I started programming I made a quick test application where I would place timer on the form and than use that timer to increase value of some variables storing seconds, minutes and hours. After a few hours of not doing anything my timer based clock would already be falling behind from computer clock by a second. Adding OnMouseMove event on the form which would simply update forms caption with mouse coordinates and then moving mouse rapidly for several minutes my timer based clock would be falling behind for several seconds already. Simply because processing all those mouse move messages would prevent on timer messages to be processed at precise intervals.

  8. #8
    @Jonax no need to appologize!
    @SilverWarior,

    Yes, polling is the thing I want to avoid. As for the precision, I don't mind that much (at least yet).

    @ administrator, it seems I edited the first post, please revert it if you can.

  9. #9
    Quote Originally Posted by nerduke View Post
    @ administrator, it seems I edited the first post, please revert it if you can.
    I reverted your last edit of the starting post in this thread as you requested.

  10. #10
    @nerduke how did you tackle the problem?

Page 1 of 2 12 LastLast

Tags for this Thread

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
  •