hohe CPU-Auslastung

  • Hallo,

    mir ist gerade was bei diesem Script aufgefallen -> https://autoit.de/index.php?page=Thread&threadID=10338

    ich kann dort anzeigen, wie viel verschiedene Festplatten sind, meine CPU-Auslastung gehtjedoch auf 40% hoch.
    An der While-Schleife liegt es ja nicht, da OnEvenAus ist (und wenn ich einen Timer einfüge, tut sich auch nichts).

    Es liegt anscheinend irgendwie an den GDIpProgress.au3 Funktionen. Nutze ich die falsch oder haben die generell so eine Auslastung?
    Ich generiere ja nur 1 - mehrere balken, mehr passiert danach nicht ... es geht um folgenden code:

    [autoit]

    Func ShowDiscSpace()
    Opt("GUIOnEventMode", 0)
    $iniReadSec = IniReadSection("Settings.ini", _GUICtrlMenu_GetItemText(GUICtrlGetHandle($MenuItem37), @GUI_CtrlId, False))
    If Not @error Then
    $height = 10
    $SpaceFree = 0
    $SpaceTotal = 0
    For $k = 1 To $iniReadSec[0][0] + 1
    $height += 30
    Next

    $GuiSpace = GUICreate("Disc Space All", 500, $height + 20, -1, -1, Default, Default, $Form1_1)
    $y = 10
    Dim $PMarquee[$iniReadSec[0][0] + 1]
    For $k = 1 To $iniReadSec[0][0]
    $Split = StringSplit($iniReadSec[$k][1], "|")
    $PMarquee[$k] = _ProgressCreate(10, $y, 480, 25, 0xAAAA00, 0xFF0000, 0xFFFF00, 0x00FF00)
    _ProgressMarquee($PMarquee[$k], 2, 0)
    _ProgressSet($PMarquee[$k], ($Split[1] - $Split[2]) * 100 / $Split[1])
    _ProgressSetText($PMarquee[$k], $iniReadSec[$k][0] & @TAB & " Total: " & $Split[1] & " GB / Used: " & $Split[1] - $Split[2] & " GB (" & Round(($Split[1] - $Split[2]) * 100 / $Split[1], 2) & "%) / Free: " & $Split[2] & " GB (" & Round($Split[2] * 100 / $Split[1], 2) & "%)")
    _ProgressSetFont($PMarquee[$k], "", 8, Default, 0xFFFFFF)
    $SpaceTotal += $Split[1]
    $SpaceFree += $Split[2]
    $y += 30
    Next
    $PMarqueeTotal = _ProgressCreate(10, $y + 20, 480, 25, 0xAAAA00, 0xFF0000, 0xFFFF00, 0x00FF00)
    _ProgressMarquee($PMarqueeTotal, 2, 0)
    _ProgressSet($PMarqueeTotal, ($SpaceTotal - $SpaceFree) * 100 / $SpaceTotal)
    _ProgressSetText($PMarqueeTotal, "All Devices" & @TAB & " Total: " & Round($SpaceTotal / 1024, 2) & " TB / Used: " & Round(($SpaceTotal - $SpaceFree) / 1024, 2) & " TB (" & Round(($SpaceTotal - $SpaceFree) * 100 / $SpaceTotal, 2) & "%) / Free: " & Round($SpaceFree / 1024, 2) & " TB (" & Round($SpaceFree * 100 / $SpaceTotal, 2) & "%)")
    _ProgressSetFont($PMarqueeTotal, "", 8, Default, 0xFFFFFF)
    GUISetState(@SW_SHOW, $GuiSpace)

    [/autoit][autoit][/autoit][autoit]

    While 1
    $msg = GUIGetMsg()

    [/autoit][autoit][/autoit][autoit]

    If $msg = $GUI_EVENT_CLOSE Then ExitLoop
    WEnd

    For $k = 1 To $iniReadSec[0][0]
    _ProgressDelete($PMarquee[$k])
    Next
    _ProgressDelete($PMarqueeTotal)

    GUIDelete($GuiSpace)
    EndIf
    Opt("GUIOnEventMode", 1)
    EndFunc

    [/autoit]
  • Hi,

    danke für die Antwort, aber wie bereits oben beschrieben, bringt ein sleep nur, dass die funktion verzögert ausgeführt wird, an der cpu-auslastung ändert sich nichts.

    gleiches kann ich auch damit belegen, wenn ich nur das gui generiere und die gdi-balken weglasse (mit der gleichen schleife ohne sleep) ist die auslastung normale unter 1%. ich schalte auch für dieses gui den on event mode AUS, d. h. (auch laut bsp) ist in der while schleife kein sleep notwendig.

  • Hallo sc4ry,

    stell mal deine INI mit ein und schreibe wle Zeile 3 ausschauen muss, damit die richtige Section gelesen wird, dann teste ich es mit deinen Werten. Kann es sein, dass du diesen Prozess (aus welchen Gründen auch immer) in einer Schleife ausführst, dann wäre es nämlich geschickter $GuiSpace nicht jedesmal zu erzeugen und wieder zu löschen sondern nur beim erstenmal erzeugen immer wieder die Daten refreshen und danch zu löschen,

    mfg (Auto)Bert

  • Hallo Sc4ry
    Also ich muss Chaoskeks zustimmen
    ein Sleep in der While chleife bewirkt wirklich wunder.
    Falls du keins hast setze es mal rein
    sleep(1) reicht schon
    Hatte auch mal ein Programm welches 100% eines Kerns in Anspruch genommen hat (solange die while schleife am "arbeiten" war)
    Wenn es das nicht ist hast du schonmal geschaut wo denn die CPU nach oben schießt?
    einfach Task Manager öffnen MSGBOXen reinsetzen zum pausieren und überprüfen wo du gerade bist
    Und mit nem Auge auf die CPU Auslastung schaun in welchem Abschnitt es nach oben geht
    So amch ich das immer :>
    MfG

  • Hi AutoBert, also die ini sieht wie folgt aus:

    Spoiler anzeigen

    [Show]
    HD=
    XviD=
    DVDR=
    Cinema=
    Serie=
    [Scan]
    Genre=
    Source=
    Resolution=
    Codec=
    Audio=
    Language=
    [D_B]
    Path=
    [FTP]
    Login=
    HomeDir=
    [All Discs]
    Test1=931.51|352.41
    Test2=931.51|352.41
    [XviD.DB]
    Test1=931.51|352.41
    [HD.DB]
    Test2=931.51|352.41

    bzgls des sleeps in der while-schleife möchte ich nochmal anmerken ;)

    soweit mir bekannt, ist der sleep nur im oneventmode nötig, bringt in meinem fall also nichts.
    zusätzlich habe ich einen sleep eingebaut, welcher nichts gebracht hat.
    zusätzlich, wenn ich die GDI-Funktionen rausnehme und die While-Schleife ohne sleep laufen lassen, ist die auslastung unter 1% (was auch beweist, dass es nicht am sleep liegt) =)

  • Hallo sc4ry,

    stell mal deine INI mit ein und schreibe wle Zeile 3


    Und wo ist die Zeile 3, vor allem kann ich nicht erkennen, was diese INI-Zeilen mit der Anzeige des freien Plattenplatzes zu tun haben soll. Ich hoffe es ist nicht alzudringend, denn ich hab jetzt erst einmal einen Termin ausser Haus, schätze aber das ich gegen Abend dazu komme es mir anzuschauen,

    mfg (Auto)Bert

  • ja sorry, der macht mir da irgendwie so komische fehler rein, ich prob mal, dass ich das hinbekomme =)

    EDIT:

    so, jetzt kannst du es sehen. ich hab mal die ganze ini genommen, da er IniReadSections macht und dann [Show], [Scan], [FTP] und [D_B] aus dem array löscht.

    übrig bleiben also [All Discs], [Xvid.DB] und [HD.DB]. Welche Sektion davon angezeigt wird, entscheidet man über ein MenuItem, also wird immer nur 1 Sektion im GUI generiert/ angezeigt.

    Er liest also zB [All Discs] aus und generiert im oben genannten Fall 2 Processbalken.

    • Offizieller Beitrag

    @ChaosKeks und @N8wolf, in einer schleife in der GuiGetMsg() aufgerufen wird sollte man es tunlichst unterlassen ein Sleep mit einzusetzen. GuiGetMsg() sorgt selbst dafür das die CPU-Last gering bleibt, ein Sleep würde nur zur Verzögerung bei Aktionen führen! Vllt. solltet ihr auch mal die Bemerkungen in der Hilfe lesen.

  • Bernd:
    So ein Quark, als ob es was ausmachen würde ob man jetzt 10ms Verzögerung hat! Ich hatte das Thema nur übersprungen und da ich grundsätzlich nicht im MsgMode scripte hab ich einfach mal den Standart-Tipp weitergegeben! Außerdem hab ich in meiner Hilfe nix über Sleep in Verbindung mit GuiGetMsg gefunden..(Ich will auch jetzt garkeine Zitate o.ä)

    So und nun B2T!

  • Bernd:
    So ein Quark, als ob es was ausmachen würde ob man jetzt 10ms Verzögerung hat! Ich hatte das Thema nur übersprungen und da ich grundsätzlich nicht im MsgMode scripte hab ich einfach mal den Standart-Tipp weitergegeben! Außerdem hab ich in meiner Hilfe nix über Sleep in Verbindung mit GuiGetMsg gefunden..(Ich will auch jetzt garkeine Zitate o.ä)

    So und nun B2T!

    Hilfe Autoit GuiGetMsg()
    ---- snip ----

    Bemerkungen
    Diese Funktion gibt die CPU automatisch wieder frei, wenn es erforderlich ist, so dass sie ruhig in Dauerschleifen benutzt werden kann, ohne die CPU vollständig auszulasten.
    -----snip ----

  • (Ich will auch jetzt garkeine Zitate o.ä)
    So und nun B2T!


    Ich wusste, dass es mindestens einen dummen gibt, der sich munter ans zitieren der Hilfe macht! gz Tigger du bist es! Siehst du da irgendwas von "Warnung: In keinem Fall mit Sleep verwenden?"
    Ich wollte jedenfalls damit nur sagen das man garnich so großen wind über meinen Post hätte machen solln.. Hab auch was dazugelernt, was ich sowieso nie brauchen werde da ich nich den MsgMode benutze und wenn ichs doch in der Zukunft brauche habe ich eine gaanze Zeile gespart. Back to Topic

    Einmal editiert, zuletzt von ChaosKeks (16. Juni 2009 um 15:48)

  • Hallo sc4ry,

    Ich habe das ganze mit deinen Werten überprüft dabei steigt die CPU-Belastung bei mir von 5% auf25%, mit sleep sogar auf 28%,

    ICH kannte die UDF GDIProgress von @progandy bisher nicht, habe selber auch noch nie was mit GDI+ gemacht wundere mich jetzt allerdings genauso wie du warum nach dem Erstellen der Gui die Auslastung nicht wieder zurückgeht. Ich hatte eigentlich nur einen kurzen Peek erwartet aber nicht eine konstante Dauerauslastung.

    Das für den Test umgebaute Skript:

    Spoiler anzeigen
    [autoit]

    #include "gdiprogress.au3"
    #include <ButtonConstants.au3>
    #include <GUIConstantsEx.au3>
    #include <StaticConstants.au3>
    #include <WindowsConstants.au3>
    Opt('GUIOnEventMode', 1)

    [/autoit] [autoit][/autoit] [autoit]

    Global $Form1_1 = GUICreate("Testaufruf für EditBox", 400, 280, 140, 150, BitOR($WS_MINIMIZEBOX, $WS_MAXIMIZEBOX, $WS_SIZEBOX))
    GUISetOnEvent($GUI_EVENT_CLOSE, '_End')
    GUICtrlCreateButton('GDIProgress &ohne Sleep', 220, 10, 150, 25)
    GUICtrlSetResizing(-1, $GUI_DOCKSIZE + $GUI_DOCKRIGHT + $GUI_DOCKTOP)
    GUICtrlSetOnEvent(-1, 'ShowDiscSpaceO')
    GUICtrlCreateButton('GDIProgress &mit Sleep', 220, 50, 150, 25)
    GUICtrlSetResizing(-1, $GUI_DOCKSIZE + $GUI_DOCKRIGHT + $GUI_DOCKTOP)
    GUICtrlSetOnEvent(-1, 'ShowDiscSpaceM')
    GUISetState()

    [/autoit] [autoit][/autoit] [autoit]

    While 1
    Sleep(120)
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    Func _End()
    GUIDelete($Form1_1)
    Exit
    EndFunc ;==>_End

    [/autoit] [autoit][/autoit] [autoit]

    Func ShowDiscSpaceO()
    ShowDiscSpace(False)
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func ShowDiscSpaceM()
    ShowDiscSpace(True)
    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func ShowDiscSpace($withSleep)
    Opt("GUIOnEventMode", 0)
    $iniReadSec = IniReadSection("Settings.ini","ALL DISCS")
    If Not @error Then
    $height = 10
    $SpaceFree = 0
    $SpaceTotal = 0
    For $k = 1 To $iniReadSec[0][0] + 1
    $height += 30
    Next

    [/autoit] [autoit][/autoit] [autoit]

    $GuiSpace = GUICreate("Disc Space All", 500, $height + 20, -1, -1, Default, Default, $Form1_1)
    $y = 10
    Dim $PMarquee[$iniReadSec[0][0] + 1]
    For $k = 1 To $iniReadSec[0][0]
    $Split = StringSplit($iniReadSec[$k][1], "|")
    $PMarquee[$k] = _ProgressCreate(10, $y, 480, 25, 0xAAAA00, 0xFF0000, 0xFFFF00, 0x00FF00)
    _ProgressMarquee($PMarquee[$k], 2, 0)
    _ProgressSet($PMarquee[$k], ($Split[1] - $Split[2]) * 100 / $Split[1])
    _ProgressSetText($PMarquee[$k], $iniReadSec[$k][0] & @TAB & " Total: " & $Split[1] & " GB / Used: " & $Split[1] - $Split[2] & " GB (" & Round(($Split[1] - $Split[2]) * 100 / $Split[1], 2) & "%) / Free: " & $Split[2] & " GB (" & Round($Split[2] * 100 / $Split[1], 2) & "%)")
    _ProgressSetFont($PMarquee[$k], "", 8, Default, 0xFFFFFF)
    $SpaceTotal += $Split[1]
    $SpaceFree += $Split[2]
    $y += 30
    Next
    $PMarqueeTotal = _ProgressCreate(10, $y + 20, 480, 25, 0xAAAA00, 0xFF0000, 0xFFFF00, 0x00FF00)
    _ProgressMarquee($PMarqueeTotal, 2, 0)
    _ProgressSet($PMarqueeTotal, ($SpaceTotal - $SpaceFree) * 100 / $SpaceTotal)
    _ProgressSetText($PMarqueeTotal, "All Devices" & @TAB & " Total: " & Round($SpaceTotal / 1024, 2) & " TB / Used: " & Round(($SpaceTotal - $SpaceFree) / 1024, 2) & " TB (" & Round(($SpaceTotal - $SpaceFree) * 100 / $SpaceTotal, 2) & "%) / Free: " & Round($SpaceFree / 1024, 2) & " TB (" & Round($SpaceFree * 100 / $SpaceTotal, 2) & "%)")
    _ProgressSetFont($PMarqueeTotal, "", 8, Default, 0xFFFFFF)
    GUISetState(@SW_SHOW, $GuiSpace)

    [/autoit] [autoit][/autoit] [autoit]

    While 1
    $msg = GUIGetMsg()
    if $withSleep then Sleep(10)
    If $msg = $GUI_EVENT_CLOSE Then ExitLoop
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    For $k = 1 To $iniReadSec[0][0]
    _ProgressDelete($PMarquee[$k])
    Next
    _ProgressDelete($PMarqueeTotal)

    [/autoit] [autoit][/autoit] [autoit]

    GUIDelete($GuiSpace)
    EndIf
    Opt("GUIOnEventMode", 1)
    EndFunc

    [/autoit]

    mfg (Auto)Bert

  • Hier kommt mal die Erklärung für die hohen Auslastungen:
    erstens ist GDI+ sehr CPU-lastig
    zweitens ist die Progressbar nicht allzu sauber programmiert. Es gibt einen Timer und alle 30-50? Millisekunden werden all neu gezeichnet. Ich hatte zwar nie so hohe Auslastungen, aber ich denke trotzdem, dass es dadurch bedingt wird. Eigentlich müsste man das auf WM_PAINT umschreiben und am besten eine eigene Fensterklasse erstellen (wie der EZ_Button oder so), dann wäre es sauber. Nur hab ich dazu gerade weder Zeit noch Lust, da das ziemlich aufwendig ist.

    //Edit: Warum hast du eigendlich das ganze _ProgressMarquee drin, wenn du nacher trotzdem über _ProgressSet einen Wert setzt? Wird es besser, wenn du das enfernst?

  • Hallo Progandy,

    ich habe die 2 Zeilen mit ProgressMarquee aukommentiert und neu getestet und es sind damit ziemlich genau 5% weniger CPU-Auslastung,

    mfg (Auto)Bert

  • Jup, das kommt davon, dass jetzt das Bild nicht gestreckt werden muss (für das Marquee wird ein Bild verkleinert).

  • Hi,

    besten dank für eure hilfe, habe _ProgressMarquee nun auch entfernt und es ist nen ticken weniger geworden.
    zumindest weiss ich nun wodran es liegt, vllt kommt ja in absehbarer zeit mal die angesprochene änderung zu diesem script =)

    ich würde es begrüßen, weil es echt ne super sache sache ist. nicht nur, dass es schick ausschaut, sondern auch die funktionalität, dass man ohne viel aufwand text in die progressbar schreiben kann (was mich erst hierzu gebracht hat).

    also, big THX =)