Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Programm verbraucht zuviel Prozessorleistung - Wie kann ich Lag verhindern? (https://www.delphipraxis.net/177745-programm-verbraucht-zuviel-prozessorleistung-wie-kann-ich-lag-verhindern.html)

Astobix 25. Nov 2013 11:55

Programm verbraucht zuviel Prozessorleistung - Wie kann ich Lag verhindern?
 
Hallo,

Ich schreibe derzeit ein Programm, indem man ein Raumschiff steuert, dass andere gegnerische Raumschiffe abschießen muss. Dabei erzeuge ich bei jedem Klick ein Image, dass meinen Laserschuss symbolisiert und dieser wird durch einen Timer im 30ms Takt (damit die Laserbewegung flüssig wird) nach oben verschoben. Wenn der Laser einen Gegner trifft, verliert dieser Leben und wenn das Leben des Gegners <= 0 ist, wird dieser zerstört. Die Gegner wiederum schießen ebenfalls zufällig Laser, denen ich dann ausweichen muss.


Soweit so gut, das Grundkonzept habe ich programmiert und es klappt auch, bis auf einige Bugs, ganz gut. Allerdings verbraucht das Programm viel zu viel Prozessorleistung. Ich komme sehr schnell an den Punkt, wo das Programm einen Kern meines Prozessors komplett auslastet und die Laser dann nur noch extrem langsam fliegen, da die verschiedenen Timer die 30ms nicht mehr schaffen.

Zudem kommt noch ein weiteres Problem. Sobald ich doublebuffered auf true setzt, um ein nerviges geflimmer zu vermeiden, verbraucht das Programm noch mehr Leistung und ist entgültig unspielbar. Gibt es dazu ressourcensparende Alternativen?
-> In der Version im Anhang ist doublebuffered=false, trotzdem laggt es ab einem gewissem Punkt.

Ansonsten weiß ich selber nicht, wie ich mein Programm "schneller" machen könnte. Ich schließe aber nicht aus, dass es dazu einige einfache Möglichkeiten gibt, die mir einfach nicht einfallen. Ich würde mich sehr freuen, wenn sich einige von euch das Programm mal ansehen könnten( -> Programm kann leider nicht in den Anhang, da die Zip zu groß ist (durch einige Bilder), deswegen gibt es das Programm hier), sobald sie Zeit haben. Ich freue mich natürlich auch über Links, wo ressourcensparendes Programmieren relativ einfach erklärt wird! :)

Das Programm wurde mit Delphi 6 geschrieben.

Gruß,
Astobix

Uwe Raabe 25. Nov 2013 12:08

AW: Programm verbraucht zuviel Prozessorleistung - Wie kann ich Lag verhindern?
 
Anstatt viele Timer, kannst du das auch in einem Timer lösen. Da ein 30ms Timer eh nicht genau nach 30ms triggered, sondern zum nächstmöglichen Zeitpunkt nach 30ms, stimmt das Timing eh nicht exakt (das siehst du auch an dem Lag).

Nimm nur einen Timer mit einem entsprechend kleinen Intervall (z.B. 30ms). Für jedes bewegte Objekt am Bildschirm berechnest du dann in dem OnTimerEvent einfach die aktuelle Position anhand der verstrichenen Zeit seit dem letzten Event und platzierst es dementsprechend.

Wenn dann die Berechnungen und die Darstellung innerhalb des Events immer noch länger brauchen als 30ms, dann ist dein System zu langsam oder deine Berechnungen zu kompliziert (oder nicht ausreichend optimiert).

Neumann 25. Nov 2013 12:48

AW: Programm verbraucht zuviel Prozessorleistung - Wie kann ich Lag verhindern?
 
Bei einem Timer kann noch passieren dass ein Event noch nicht abgearbeitet ist wenn der nächste kommt, was zu den Problemen mit der Last führen kann. Einfache Abhilfe ist folgendes:

Delphi-Quellcode:
  if Timer1.Tag=1 then
  exit;
  Timer1.Tag:=1;
  ..Tuwas;
  Timer1.Tag:=0;

Sherlock 25. Nov 2013 12:53

AW: Programm verbraucht zuviel Prozessorleistung - Wie kann ich Lag verhindern?
 
Alternativ deaktiviert man den Timer in der Zeit, in der man ihn abarbeitet.

Sherlock

Uwe Raabe 25. Nov 2013 13:00

AW: Programm verbraucht zuviel Prozessorleistung - Wie kann ich Lag verhindern?
 
Zitat:

Zitat von Neumann (Beitrag 1237334)
Bei einem Timer kann noch passieren dass ein Event noch nicht abgearbeitet ist wenn der nächste kommt

Das kann aber nur passieren, wenn innerhalb des Event-Handlers sowas wie
Delphi-Quellcode:
Application.ProcessMessages
aufgerufen wird, was ich auf jeden Fall vermeiden würde! Andernfalls sind die Timer-Events durch die Message-Queue schon serialisiert und die gezeigte Blockung ist überflüssig. Natürlich kann nach dem Durchlaufen des Event-Handlers schon die nächste Timer-Message vorliegen, aber dann ist eben das System wirklich zu langsam. Dann würde das von Sherlock vorgeschlagene abschalten die Sache etwas entzerren. Andererseits würde ich dann wohl einen ganz anderen Ansatz wählen.

Sir Rufo 25. Nov 2013 13:40

AW: Programm verbraucht zuviel Prozessorleistung - Wie kann ich Lag verhindern?
 
Du musst immer die Zeit berechnen, die zwischen dem letzten Aufruf und dem aktuellen Aufruf vergangen ist und dann berechnen, wie viele Schritte eigentlich hätten erfolgen sollen.
Die noch verbleibende Zeit speicherst du als Reserve und wird beim nächsten Schritt berücksichtigt.

Diese Schritte werden dann ausgeführt und dann wird das Zeichnen einmalig veranlasst.

Hier mal eine Klasse, die dieses berücksichtigt
Delphi-Quellcode:
unit Animator;

interface

  uses
    Classes,
    SysUtils,
    ExtCtrls;

  type
    TAnimator = class( TComponent )
    private
      FLocked    : Boolean;
      FTimer     : TTimer;
      FAccu      : Integer;
      FLastCall  : TDateTime;
      FOnStep    : TNotifyEvent;
      FOnPaint   : TNotifyEvent;
      FResolution : Cardinal;
      procedure TimerEvent( Sender : TObject );
      procedure SetResolution( const Value : Cardinal );
      function CalculateSteps : Integer;
      function GetEnabled : Boolean;
      procedure SetEnabled( const Value : Boolean );
      procedure DoStep;
      procedure DoPaint;
    public
      constructor Create( AOwner : TComponent ); override;
      destructor Destroy; override;

      // Event für den Berechnungs-Schritt
      property OnStep : TNotifyEvent read FOnStep write FOnStep;
      // Event für die Zeichen-Schritt
      property OnPaint : TNotifyEvent read FOnPaint write FOnPaint;
      // Auflösung in Millisekunden
      property Resolution : Cardinal read FResolution write SetResolution default 30;
      property Enabled : Boolean read GetEnabled write SetEnabled default True;
    end;

implementation

  uses
    DateUtils;

  { TAnimator }

  function TAnimator.CalculateSteps : Integer;
    var
      LNow : TDateTime;
      LSpan : Integer;
    begin
      LNow := Now;

      // Zeitspanne zwischen letzem Aufruf und Jetzt
      // plus dem noch nicht berücksichtigtem Zeitvorrat
      LSpan := MilliSecondsBetween( LNow, FLastCall ) + FAccu;
      // Anzahl der Schritt pro Zeitauflösung
      Result := LSpan div FResolution;
      // Restzeit in den Zeitvorrat
      FAccu := LSpan - Result * FResolution;

      FLastCall := LNow;
    end;

  constructor TAnimator.Create( AOwner : TComponent );
    begin
      inherited;
      FLastCall      := Now;
      FResolution    := 30;
      FTimer         := TTimer.Create( Self );
      FTimer.OnTimer := TimerEvent;
      FTimer.Interval := 1;
      FTimer.Enabled := True;
    end;

  destructor TAnimator.Destroy;
    begin

      inherited;
    end;

  procedure TAnimator.DoPaint;
    begin
      if Assigned( OnPaint )
      then
        OnPaint( Self );
    end;

  procedure TAnimator.DoStep;
    begin
      if Assigned( OnStep )
      then
        OnStep( Self );
    end;

  function TAnimator.GetEnabled : Boolean;
    begin
      Result := FTimer.Enabled;
    end;

  procedure TAnimator.SetEnabled( const Value : Boolean );
    begin
      if Value = Enabled
      then
        Exit;

      if Value
      then
      begin

        // Wird der Timer wieder eingeschaltet, dann
        // LastCall und Accu wieder zurücksetzen

        FLastCall := Now;
        FAccu    := 0;
      end;

      FTimer.Enabled := Value;
    end;

  procedure TAnimator.SetResolution( const Value : Cardinal );
    begin
      if ( Value = FResolution ) or ( Value = 0 )
      then
        Exit;

      FResolution := Value;
    end;

  procedure TAnimator.TimerEvent( Sender : TObject );
    var
      LSteps : Integer;
    begin
      if FLocked
      then
        Exit;

      FLocked := True;
      try

        LSteps := CalculateSteps;

        if LSteps = 0
        then
          Exit;

        while ( LSteps > 0 ) do
        begin
          DoStep;
          Dec( LSteps );
        end;

        DoPaint;

      finally
        FLocked := False;
      end;
    end;

end.
Und ein kleines Testprogramm, was drei Shapes unterschiedlich schnell über die Form fliegen lässt
Delphi-Quellcode:
unit ViewMain;

interface

  uses
    Animator,
    Windows,
    Messages,
    SysUtils,
    Variants,
    Classes,
    Graphics,
    Controls,
    Forms,
    Dialogs,
    ExtCtrls;

  type
    TFloatPoint = record
      x, y : Extended;
    end;

    TMainView = class( TForm )
      Shape1 : TShape;
      Shape2 : TShape;
      Shape3 : TShape;
      procedure FormCreate( Sender : TObject );
    private
      FShape1Pos : TFloatPoint;
      FShape2Pos : TFloatPoint;
      FShape3Pos : TFloatPoint;
      FAnimator : TAnimator;
      procedure AnimatorStep( Sender : TObject );
      procedure AnimatorPaint( Sender : TObject );
    public

    end;

  var
    MainView : TMainView;

implementation

{$R *.dfm}

  procedure TMainView.AnimatorPaint( Sender : TObject );
    begin
      // Hier wird das Zeichnen der Oberfläche veranlasst

      Shape1.Top := Round( FShape1Pos.y );
      Shape1.Left := Round( FShape1Pos.x );

      Shape2.Top := Round( FShape2Pos.y );
      Shape2.Left := Round( FShape2Pos.x );

      Shape3.Top := Round( FShape3Pos.y );
      Shape3.Left := Round( FShape3Pos.x );
    end;

  procedure TMainView.AnimatorStep( Sender : TObject );
    begin
      // Hier erfolgen NUR die Berechnungen

      // Shape1

      // Geschwindigkeit 500 Pixel/Sekunde
      FShape1Pos.y := FShape1Pos.y - ( 500 / 1000 * FAnimator.Resolution );

      // Wenn es nach oben rausrutscht, dann von unten wieder komplett reinkommen lassen
      if FShape1Pos.y < 0
      then
        FShape1Pos.y := FShape1Pos.y + Self.Height - Shape1.Height;

      // Shape2

      // Geschwindigkeit 200 Pixel/Sekunde
      FShape2Pos.y := FShape2Pos.y - ( 200 / 1000 * FAnimator.Resolution );

      // Wenn es nach oben rausrutscht, dann von unten wieder komplett reinkommen lassen
      if FShape2Pos.y < 0
      then
        FShape2Pos.y := FShape2Pos.y + Self.Height - Shape2.Height;

      // Shape3

      // Geschwindigkeit 800 Pixel/Sekunde
      FShape3Pos.y := FShape3Pos.y - ( 800 / 1000 * FAnimator.Resolution );

      // Wenn es nach oben rausrutscht, dann von unten wieder komplett reinkommen lassen
      if FShape3Pos.y < 0
      then
        FShape3Pos.y := FShape3Pos.y + Self.Height - Shape3.Height;

    end;

  procedure TMainView.FormCreate( Sender : TObject );
    begin

      // Positionen der Objekte merken

      FShape1Pos.x := Shape1.Left;
      FShape1Pos.y := Shape1.Top;

      FShape2Pos.x := Shape2.Left;
      FShape2Pos.y := Shape2.Top;

      FShape3Pos.x := Shape3.Left;
      FShape3Pos.y := Shape3.Top;

      // Animator initialisieren

      FAnimator        := TAnimator.Create( Self );
      FAnimator.OnStep := AnimatorStep;
      FAnimator.OnPaint := AnimatorPaint;
    end;

end.

Popov 25. Nov 2013 13:49

AW: Programm verbraucht zuviel Prozessorleistung - Wie kann ich Lag verhindern?
 
Eine Alternative wäre - du richtest dich nicht nach Timer, sondern nach möglichen Fps.

Beispiel: du hast einen Ball der auf einem 1024 waagerechtem Bildschirm von links nach rechts bewegt werden soll.

- Möglichkeit 1: du bewegst den Ball jeweils um einen Pixel nach rechts. Damit das alles innerhalb einer Sekunde angezeigt wird, müssten 1024 Bilder pro Sekunde aufgebaut werden. Wird wohl nicht klappen, wenn höchstens 100. also wird der Ball 10 Sekunden brauchen. Das Spiel ist flüssig, wirkt aber zu langsam.

- Möglichkeit 2: du analysierst wie viel Bilder pro Sekunde gerade möglich sind, z. B. 30. Somit wird der Ball nicht um 1 Pixel pro Frame bewegt, sondern 1024 / 30 = 35 Pixel. Der Ball passiert den Bildschirm innerhalb einer Sekunde. Wenn FPS zu gering wird, hackt das Spiel, bleibt aber in der Zeit.

Sir Rufo 25. Nov 2013 14:05

AW: Programm verbraucht zuviel Prozessorleistung - Wie kann ich Lag verhindern?
 
@Popov

Genau so macht man das eben nicht.

Man ermittelt, wieviele Zeiteinheits-Schritte man aktuell abarbeiten muss und arbeitet diese ab.
Dann klatscht man das Ergebnis auf den Bildschirm (das dauert idR am längsten).

Wie oft man das auf den Bildschirm bekommt, das ist dann die FPS (und die ist abhängig von der Komplexität der Animation sowie der aktuell verfügbaren Rechenleistung).

Andersherum fällt man nur über die eigenen Füße (erst FPS berechnen und abhängig davon die Berechnung der Positionen).

hathor 25. Nov 2013 14:23

AW: Programm verbraucht zuviel Prozessorleistung - Wie kann ich Lag verhindern?
 
Kleiner Tipp:

Wenn es "nur" auf LCD mit 60Hz Bildfrequenz laufen soll, dann macht es keinen Sinn, mehr als 60 Änderungen im Bild zu erzeugen.
Es wird nicht angezeigt!
Beispiel:
Es soll sich etwas vom linken zum rechten Bildrand bewegen bei 1920 horizontale Pixel und einer Geschwindigkeit von 1920 Pixel/sec, dann muss man nur 1920/60=32 Positionen berechnen und nicht 1920!
Bei 120Hz Bildfrequenz sind es entsprechend 64 Positionen. Der Rest ist Luxus.

Sir Rufo 25. Nov 2013 14:43

AW: Programm verbraucht zuviel Prozessorleistung - Wie kann ich Lag verhindern?
 
Liste der Anhänge anzeigen (Anzahl: 1)
Ich habe da mal den Animator noch etwas angepasst, und der ermittelt jetzt auch noch FPS (mit einer Glättung).

Auf der Form ist jetzt noch eine Checkbox zum Ein-/Ausschalten des Animators und ein SpinEdit zum Anpassen der Resolution (Zeiteinheit in Millisekunden).

Durch das Erhöhen dieser Zeiteinheit sieht man, dass das Ergebnis mehr ruckelt und je kleiner, umso flüssiger wird es.

Man sieht aber auch, dass das System nicht aus dem Tritt kommt und die Shapes immer passend ihre Bahnen ziehen und beim Zeichnen sind die da, wo man es auch zu dem Zeitpunkt vermuten würde.

Anhang mit Sourcen und kompilierter EXE

Astobix 25. Nov 2013 14:45

AW: Programm verbraucht zuviel Prozessorleistung - Wie kann ich Lag verhindern?
 
Schonmal vielen Dank für die Tipps/Hilfe! Ich probiere das dann mal aus.

Einige Fragen sind mir aber noch geblieben:

1. Die Frage mit dem Doublebuffering. Sobald ich es auf true setzte, verdoppelt sich fast die benötigte ProzessorLeistung. Wenn ich es auf false belasse, flimmert alles. Gibt es Alternativen, die weniger Ressourcen kosten, aber trotzdem das Flimmern verhindern?

2. Ich habe mich noch nicht wirklich mit Threads auseinandergesetzt, würde es irgendeinen Vorteil bringen, das Programm in mehrere Threads aufzuteilen? Kann man damit das Programm auf mehrere Kerne aufteilen - und ist das sinnvoll?

Sir Rufo 25. Nov 2013 14:49

AW: Programm verbraucht zuviel Prozessorleistung - Wie kann ich Lag verhindern?
 
  1. Logisch, denn jede Veränderung veranlasst das System den Bildschirm neu zu zeichnen. Beim DoubleBuffer sogar jeweils doppelt.
    Benutze keine Komponenten, sondern zeichne alles selber auf ein Bitmap. Wenn du mit dem Bitmap fertig bist, dann zeichne dieses Bitmap auf die Form -> Das System muss jetzt nur einmal neu zeichnen.
  2. Die Threads werden dir bislang noch nicht weiterhelfen, denn der größte Aufriss ist das Zeichnen auf dem Bildschirm und der darf eh nur synchronisiert im Hauptthread erfolgen.

Popov 25. Nov 2013 15:03

AW: Programm verbraucht zuviel Prozessorleistung - Wie kann ich Lag verhindern?
 
Zitat:

Zitat von Sir Rufo (Beitrag 1237349)
@Popov

Genau so macht man das eben nicht.

Das will ich dir glauben, aber sieh mal - ich habe einen einfachen Rechner und gelegentlich installiere ich einen 3D Egoshooter, der für meinen Rechner einfach zu neu ist. Ergebnis, ich bekomme in einer Sekunde mal ein Frame zu sehen. Nun könnte man meinen, dass der edle Krieger für die 100 Meter deshalb 100 Sekunden braucht, denn wenn nichts angepasst wird, dann müssen alle Frames abgespielt werden.

Passiert eben nicht. Was ich sehe ist ein Frame pro Sekunde und den edlen Krieger in 10 Meter Abständen (vorausgesetzt er läuft die 10 Meter in einer Sekunde).

Das Spiel läuft also in Realtime ab. Und nichts anderes habe ich geschrieben. Entweder läuft das Spiel in Zeitlupe ab oder es hackt, weil es in Realtime abläuft. Vielleicht habe ich das falsch ausgedrückt, hab aber das richtige gemeint. Das Problem ist nur, dass man nicht überall immer eine Welt Engine hat, so dass man sich nach Abstand richten kann.

Sir Rufo 25. Nov 2013 15:09

AW: Programm verbraucht zuviel Prozessorleistung - Wie kann ich Lag verhindern?
 
Zitat:

Zitat von Popov (Beitrag 1237360)
Zitat:

Zitat von Sir Rufo (Beitrag 1237349)
@Popov

Genau so macht man das eben nicht.

Das will ich dir glauben, aber sieh mal - ich habe einen einfachen Rechner und gelegentlich installiere ich einen 3D Egoshooter, der für meinen Rechner einfach zu neu ist. Ergebnis, ich bekomme in einer Sekunde mal ein Frame zu sehen. Nun könnte man meinen, dass der edle Krieger für die 100 Meter deshalb 100 Sekunden braucht, denn wenn nichts angepasst wird, dann müssen alle Frames abgespielt werden.

Passiert eben nicht. Was ich sehe ist ein Frame pro Sekunde und den edlen Krieger in 10 Meter Abständen (vorausgesetzt er läuft die 10 Meter in einer Sekunde).

Das Spiel läuft also in Realtime ab. Und nichts anderes habe ich geschrieben. Entweder läuft das Spiel in Zeitlupe ab oder es hackt, weil es in Realtime abläuft. Vielleicht habe ich das falsch ausgedrückt, hab aber das richtige gemeint. Das Problem ist nur, dass man nicht überall immer eine Welt Engine hat, so dass man sich nach Abstand richten kann.

Ja du hast wohl das richtige gemeint, allerdings ist die FPS die Resultierende daraus und nicht das, was man zur Berechnung nimmt ;)

Popov 25. Nov 2013 15:58

AW: Programm verbraucht zuviel Prozessorleistung - Wie kann ich Lag verhindern?
 
Das stimmt, nur hat man wie gesagt nicht immer eine Welt bei der man sich an Zeiten oder Abstand orientieren kann. Das mit FPS ist ein kleiner Trick den ich mal ausprobiert habe und der eigentlich gut klappt.

Sir Rufo 25. Nov 2013 16:54

AW: Programm verbraucht zuviel Prozessorleistung - Wie kann ich Lag verhindern?
 
Zitat:

Zitat von Popov (Beitrag 1237369)
Das stimmt, nur hat man wie gesagt nicht immer eine Welt bei der man sich an Zeiten oder Abstand orientieren kann. Das mit FPS ist ein kleiner Trick den ich mal ausprobiert habe und der eigentlich gut klappt.

Hast du da mal ein Beispiel?

Eigentlich geht es bei Geschwindigkeit immer um Strecke pro Zeiteinheit.

Popov 25. Nov 2013 17:39

AW: Programm verbraucht zuviel Prozessorleistung - Wie kann ich Lag verhindern?
 
Hatte ich. Ich hab mal ein kleines Spiel für zwischendurch programmiert, bzw. bin immer noch dabei (mit langen Pausen dazwischen). Etwas belangloses was man im Büro in der Mittagspause spielen kann. Das spezielle an dem Programm war, dass da plötzlich paar tausend Objekte auf dem Bildschirm rumschwirren konnten (theoretisch). Das höchste bei einem Test waren 15.000 Bitmaps. Das ergab 5 FPS. D. h. in 1/5 Sekunde wurden 15.000 Bitmaps in die Zielbitmap kopiert.

Nicht dass das normal war, aber es konnte passieren. Das Programm lief bei 5 FPS somit in Zeitlupe ab, so dass man plötzlich keine Probleme hatte die seine Abschüsse zu machen. Also habe ich das so umprogrammiert wie ich es oben geschrieben habe.

Funktioniert hat es, nur war ich damit trotzdem nicht glücklich. Also habe ich das Programm komplett neu geschrieben und dieses mal richtig optimiert, so dass ich jetzt 225.000 Objekte brauche um auf 5 FPS zu kommen (ich hab es tatsächlich gemessen).

Auf was ich hinaus will: es hat funktioniert, nur habe ich den Code nicht mehr. In der neuen Version habe ich auf Bitmaps verzichtet und die Objekte gezeichnet. Das geht schneller.

Aber was ich geschrieben habe, funktioniert.

Sir Rufo 25. Nov 2013 17:58

AW: Programm verbraucht zuviel Prozessorleistung - Wie kann ich Lag verhindern?
 
Ok, evtl. löse ich die Probleme lieber auf direkte Art ;)

Popov 25. Nov 2013 20:42

AW: Programm verbraucht zuviel Prozessorleistung - Wie kann ich Lag verhindern?
 
Das war einfacher als es sich anhört und hätte ich das nicht neu gemacht wäre das eine gute Idee gewesen.

Sir Rufo 25. Nov 2013 21:38

AW: Programm verbraucht zuviel Prozessorleistung - Wie kann ich Lag verhindern?
 
Zitat:

Zitat von Popov (Beitrag 1237398)
Das war einfacher als es sich anhört und hätte ich das nicht neu gemacht wäre das eine gute Idee gewesen.

Das weiß ich, weil es in meinen Augen durch die Brust ins Auge ist ;)

Popov 25. Nov 2013 22:40

AW: Programm verbraucht zuviel Prozessorleistung - Wie kann ich Lag verhindern?
 
Wieso? Weil nach dieser Idee das Programm sich der Auslastung anpasst?

Betrachten wir die Natur. Was passiert wenn der Mensch nicht genug Nahrung bekommt? Ok, er nimmt ab, aber was passiert vorher? Der Körper stellt sich drauf ein (liest man oft) und nutzt die vorhandene Nahrung effizienter aus. Hört sich hoch interessanter an, fast so, als ob der Körper aus 1 Joule 2 machen könnte. Geht natürlich nicht, aber wie geht sonst? Ganz einfach, der Körper wird träge. So verbrennt er weniger Kalorien. Der Körper passt sich den Gegebenheiten an, also durch die Brust ins Auge?

Der schöne Günther 25. Nov 2013 23:12

AW: Programm verbraucht zuviel Prozessorleistung - Wie kann ich Lag verhindern?
 
Ich verstehe es aber auch noch nicht so ganz.

Ich kenne es eigentlich auch entweder nur so, dass es einfach langsamer wird wenn die Frames nicht mehr schnell genug berechnet werden können (eher ungewöhnlich, kommt aber durchaus vor) - Oder Dinge wie Benutzereingaben, Physik, Wegfindung usw laufen vom Grafikrendering getrennt. Wenn ein Bild nun 60, 70 ms dauert, meinetwegen. Aber deswegen kann bsp. die Netzwerkkommunikation oder KI doch nicht immer auf die Grafik warten.

Was aber natürlich vorkommt (leider zu selten) ist eine Anpassung des Detailgrads wie verschiede LOD-Stufen, Sichtweite oder auch gröber arbeitende KI wenn die FPS in den Keller gehen.


Wäre es, im konkreten Spaceshooter-Beispiel in Delphi denn tragbar, das Bitmap-Pinseln in einen Thread auszulagern während der VCL-Hauptthread sich 60 mal in der Sekunde das zuletzt gerenderte Bitmap anschaut und evtl auf das Formular pinselt? Oder vielleicht auch nur für tolle Grafikeffekte - Explosions-Sprites müssen ja nicht mit der gleichen Geschwindigkeit animiert und über das fertige Bild gelegt werden wie die fliegenden Raumschiffe und der Spieler...

Popov 26. Nov 2013 00:17

AW: Programm verbraucht zuviel Prozessorleistung - Wie kann ich Lag verhindern?
 
Liste der Anhänge anzeigen (Anzahl: 1)
Das war nur ein Ansatz, nicht die Lösung. Kann jeder machen wie er will.

Und für die Bastler - wer Lust hat kann diesen "Bildschirmschoner" optimieren. Er ist zu langsam ;)

hathor 26. Nov 2013 09:20

AW: Programm verbraucht zuviel Prozessorleistung - Wie kann ich Lag verhindern?
 
Liste der Anhänge anzeigen (Anzahl: 2)
Timer.Interval:=16;
const speed = 72;

Ergebnis im Anhang.
Im 2.Anhang:
const speed = 100;
MIN (mein Wert:27) und MAX (mein Wert:142) hinzugefügt,
Caption verbessert.

Der schöne Günther 26. Nov 2013 09:35

AW: Programm verbraucht zuviel Prozessorleistung - Wie kann ich Lag verhindern?
 
Liste der Anhänge anzeigen (Anzahl: 1)
Meine Augen :roteyes:

Das jetzt noch zweifach im Anagylph-Verfahren rendern für den 3D-Effekt und wer dann am längsten ohne epileptischen Anfall bleibt hat gewonnen :smile2:

himitsu 26. Nov 2013 09:39

AW: Programm verbraucht zuviel Prozessorleistung - Wie kann ich Lag verhindern?
 
Ich würde nicht davon ausgehen, daß ein TTimer genau läuft.
Diese Messages sind quasi niedrig Priorisiert.

Ist das Programm/System ausgelastet, dann sind die Timer es, welche praktisch als erstes keine Messages mehr rausgeben.
Außerdem werden sie nur via PostMessage in die MessageQueue eingereiht, als selbst wenn sie pünktlich rausgehen, werden sie nicht sofort abgearbeitet.
Dauert die Abarbeitung länger, dann werden neue Messages nicht rausgegeben, solange noch Eine in der Queue steckt, was dann für fehlende Zeit sorgt, wenn man die Spielgeschwindigkeit an den Takt der Messages hängt. Und auf langsameren rechnern, welche die einzelnen Messages nicht schnellgenug verarbeiten, wird es dann, wie schon mitbekommen, auch noch langsamer.

Wenn man den zeitlichen Ablauf wirklich an einen zeit-synchronen Zähler (Uhrzeit oder Counter ala GetTickCount oder schnellerere MultiMediaTimer) hängt und die Wegstrecke nicht von der Verarbeitungsgeschwindigkeit, sondern von der Uhrzeit abhängig macht, dann ist es egal, ob der Rechner 500 oder nur 2 FPS schafft ... die Wegstrecke ist dann praktisch gleich. (vorausgesetzt die Wegstrecke ist entsprechend vorhersehbar, bzw. nachberechenbar)

So könnte man dann über Pausen zwischen den Verarbeitungen auch die CPU-Auslastung steuern, bzw. die überlastete CPU regelt das von selber runter, ohne daß es in einer Zeitlupe endet.


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:19 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz