Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Tchart Datenerfassung >> Zuviel Overhead ... (https://www.delphipraxis.net/135940-tchart-datenerfassung-zuviel-overhead.html)

psd-sign 20. Jun 2009 17:13


Tchart Datenerfassung >> Zuviel Overhead ...
 
Hi,

ich bastel gerade an einem Tool, dass mir Prozessor- und RAM Last bei Aufruf einer externen Exe auslesen soll. Dabei stosse ich auf folgendes Problem:

Wenn ich einen Graphen mit TChart zeichne, dann erzeugt die Datenerfassung einen zu hohen Overhead. Anders ausgedrückt:

Szenario 1
- Ich öffne den Taskmanager
- Die CPU Auslastung liegt so bei 2-3% im IDLE
- Ich starte die zu testende TEST.EXE über den Explorer
- nach einer Spitze pendelt sich die CPU bei 20% ein.

Szenario 2 (ungewollt)
- Ich öffne den Taskmanager
- Die CPU Auslastung liegt so bei 2-3% im IDLE
- Ich öffne meine Delphi Anwendung
- Die CPU Auslastung liegt so bei 3-5%
- Ich öffne per Delphi Anwendung meine TEST.EXE
- Während TEST.EXE aktiv ist, sammelt Delphi in einem Intervall von 100 Millisekunden Daten über CPU & RAM Auslastung
- Die CPU Auslastung liegt bei 80% und pendelt dort + / - 5%.

Logische Folge: Ich erzeuge mit meiner Anwendung, also mit dem Datensammeln einen ungewollten Overhead. Wie verhindere ich das?

Hier meine Vorgehensweise bei der Datensammlung :
Delphi-Quellcode:
  [....]

// MESSVORGANG START ....
  QueryPerformanceFrequency(Freq_FPC);
  QueryPerformanceCounter(Start_FPC);

  // Datei öffnen:
  ShellExecute(0,Nil,PCHar(frm_main.Edit_filename.Text),Nil,Nil,SW_NORMAL);

  start_gtk := gettickcount;

  ACT_GTK := Start_GTK;
  i := 1;
  prot_string := '';



  while IsExeRunning(EXE_string) = true do
  begin

  x:= strtoint(ComboBox_intervall.text);

    // Immer nur alle x Millisekunden eine Messung. Sonst erzeugt die
    // Messung zuviel CPU Last und verfälscht so das Ergebnis
    // --> zu grosser Rucksack!
    if (GetTickCount - ACT_GTK) >= x then
    begin
      ACT_GTK := GetTickCount;

      // RAM Werte spezifizerien:
      if get_global_ram_usage_percentage > G_Max_ram_use then
        G_Max_ram_use := get_global_ram_usage_percentage;

      if get_global_ram_usage_percentage < G_Min_ram_use then
        G_Min_ram_use := get_global_ram_usage_percentage;

      // CPU Werte spezifizerien:
      G_Act_cpu_use := GetSystemCPUUsage;
      G_AVG_cpu_use := G_AVG_cpu_use + G_Act_cpu_use;
      if G_Act_cpu_use > G_Max_cpu_use then
        G_Max_cpu_use := G_Act_cpu_use;

      if G_Act_cpu_use < G_Min_cpu_use then
        G_Min_cpu_use := G_Act_cpu_use;

      // VRAM WERTE setzen:
      G_Act_vram_use := get_global_vram_usage_percentage;
      G_AVG_vram_use := G_AVG_vram_use + G_Act_vram_use;
      if G_Act_vram_use > G_Max_vram_use then
        G_Max_vram_use := G_Act_vram_use;

      if G_Act_vram_use < G_Min_vram_use then
        G_Min_vram_use := G_Act_vram_use;

      // PAGE WERTE setzen:
      G_Act_page_use := get_global_page_usage_percentage;
      G_AVG_page_use := G_AVG_page_use + G_Act_page_use;
      if G_Act_page_use > G_Max_page_use then
        G_Max_page_use := G_Act_page_use;

      if G_Act_page_use < G_Min_page_use then
        G_Min_page_use := G_Act_page_use;


      // Charts aktualisierern:
      chart_vram.Series[0].AddXY(i, G_Act_vram_use, '', clTeeColor);                 chart_vram.Update; chart_vram.BottomAxis.Maximum := i ;
      chart_page.Series[0].AddXY(i, G_Act_page_use, '', clTeeColor);                 chart_page.Update; chart_page.BottomAxis.Maximum := i ;
      chart_cpu.Series[0].AddXY(i, G_Act_cpu_use, '', clTeeColor);                   chart_cpu.Update; chart_cpu.BottomAxis.Maximum := i ;
      chart_ram.Series[0].AddXY(i, get_global_ram_usage_percentage, '', clTeeColor); chart_ram.Update; chart_ram.BottomAxis.Maximum := i ;

      inc(i);
    end;


  end;

  stop_gtk := gettickcount;

  QueryPerformanceCounter(Stop_FPC);
  // MESSVORGANG ENDE ....

[...]
P.S.:
- Für das Sammeln der CPU-Auslastung benutze ich die Funktionen aus der AdCpuUsage.pas von Alexey Dynnikov (http://www.aldyn.ru/products/cpu_usage/)
- Für das Sammeln der RAM daten nutze ich GlobalMemoryStatus

sx2008 20. Jun 2009 19:08

Re: Tchart Datenerfassung >> Zuviel Overhead ...
 
Deine Art zu Warten nennt man busy waiting und die kostet CPU Leistung.
Du musst deinen Prozess mit Sleep auch mal etwas schlafen legen oder einen Timer benützen
Delphi-Quellcode:
// Immer nur alle x Millisekunden eine Messung. Sonst erzeugt die
// Messung zuviel CPU Last und verfälscht so das Ergebnis
// --> zu grosser Rucksack!
    if (GetTickCount - ACT_GTK) >= x then
    begin
    end
    else        //
      Sleep(50); // neu


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:29 Uhr.

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