Programm wird langsamer



  • Hi
    Ich habe folgendes Problem:
    Ich starte die Release-Version meines Programms, lade in dem Programm Datei A und messe die Dauer die es braucht bis es beendet ist. Beim ersten mal braucht es mit Datei A zB 390 Sekunden (genau solange wie es brauchen sollte).
    Danach starte ich das Programm erneut diesmal mit Datei B. Wenn ich nun nachdem das Programm mit Datei B fertig ist erneut starte und wieder die Zeit für Datei A messe braucht das Programm über 1 Minute länger als zuvor.
    Welche Ursachen kann das grundsätzlich haben? Kann mir das nicht erklären, das Programm wird natürlich jedes mal komplett beendet bevor es erneut gestartet wurde.

    Vielen Dank für eure Hilfe
    Gruß Zaus



  • Caches liegen nahe. Da gibt's verschiedenste. Von der Festplatte selbst bis hin zum Prozessor bzw. falls du die Datei richtig ausliest, vielleicht nur hin bis zum I/O-Controller haben alle Zwischenspeicher.

    MfG SideWinder



  • Nach einem Neustart sind die Zeiten anfangs auch wieder normal.
    Auf was muss ich denn in meinem Code achten, dass das nicht passiert. Es ist sehr wichtig, dass das Programm in der vorgegeben Zeit abläuft und das nicht nur eine begrenze Anzahl lang.
    Gruß Zaus



  • Wie groß sind die Dateien?



  • Zwischen 5 und 100KB. Die Dateien die benutzt wurden als das Problem auftrat waren ca 75KB groß. Der Inhalt der Datei wird Anfangs (vor der Zeitmessung) komplett in einem vector<int> gespeichert.

    Der Fehler ist übrigens nicht reproduzierbar. Gestern konnte ich 20 Durchläufe machen ohne dass das Programm langsamer wurde. Manchmal passiert das aber schon nach dem 2. Durchlauf....

    Gruß zaus



  • Also bei ein paar 100K und einer Laufzeit von 390 Sekunden ist es sicher nicht der Cache. Mehr als ein paar Sekunden um 100K einzulesen und zu parsen sind verdammt lang. Was machst du?



  • Das Einlesen der Datei ist in den 390 Sekunden gar nicht eingerechnet.
    Der Großteil der 390 Sekunden kommt durch Sleep() Befehle zustande. Mir ist klar, dass dies bei einem Nicht-Echtzeitfähigen Betriebssystem nur auf 10ms genau geht und dadurch bei 1000 Aufrufen auch die ein oder andere Sekunde Abweichung auftreten kann. Aber diese Schwankung, dass das Programm auf einmal 20% länger läuft als es sollte kann ich mir nicht erklären.



  • Zaus schrieb:

    Der Großteil der 390 Sekunden kommt durch Sleep() Befehle zustande.

    Scherzkeks! Mit Sleep im Programm kannste jede Gang-Ungenauigkeit doch wieder supi auffangen. Einfach mal kürzer Sleepen, wenn es davor zu lang war. Dazu mußt Du nur jedesmal vor Sleep auf eine Uhr schauen und mitschreiben, wie lange Du bisher geschlafen haben solltest.

    static_assert(CLOCKS_PER_SEC==1000,"Programmierer war doch zu faul");
    int slept=0;
    void TheOtherSleep(int ms)
    {
       slept+=ms;
       int toSleep=slept-clock();
       if(toSleep<0)
          toSleep=0;
       Sleep(toSleep);
    }
    


  • Zaus schrieb:

    Mir ist klar, dass dies bei einem Nicht-Echtzeitfähigen Betriebssystem nur auf 10ms genau geht und dadurch bei 1000 Aufrufen auch die ein oder andere Sekunde Abweichung auftreten kann.

    Sag sowas nicht. Bei einem Extzeitfähigen Betriebssystem können noch viel größere Schwankungen auftreten.
    Siehe hier zur Bedeutung von Echtzeitfähigkeit
    http://www.c-plusplus.net/forum/viewtopic-var-t-is-269324-and-postdays-is-0-and-postorder-is-asc-and-start-is-0.html



  • Echtzeit bedeutet "nur" garantiert rechtzeitig. Das können 2ms oder 2 Sekunden oder was auch immer sein.



  • volkard schrieb:

    Zaus schrieb:

    Der Großteil der 390 Sekunden kommt durch Sleep() Befehle zustande.

    Scherzkeks! Mit Sleep im Programm kannste jede Gang-Ungenauigkeit doch wieder supi auffangen. Einfach mal kürzer Sleepen, wenn es davor zu lang war. Dazu mußt Du nur jedesmal vor Sleep auf eine Uhr schauen und mitschreiben, wie lange Du bisher geschlafen haben solltest.

    static_assert(CLOCKS_PER_SEC==1000,"Programmierer war doch zu faul");
    int slept=0;
    void TheOtherSleep(int ms)
    {
       slept+=ms;
       int toSleep=slept-clock();
       if(toSleep<0)
          toSleep=0;
       Sleep(toSleep);
    }
    

    Wenn das Programm so extrem langsamer wird wie bei mir (über 20%) dann ist es für mich leider keine Alternative das nächste mal kürzer zu schlafen. Trotzdem danke für deine Mühe.
    Aber das kann ja auch nicht des Rätsels Lösung sein. Wie kann ich durch die Sleep-Befehle auf einmal so einen großen Unterschied bekommen? (Im Moment tritt der Fehler übrigens nicht mehr auf) Auch das Umstellen der Priorität auf "Realtime" brachte keinen Effekt.

    Ich will mich jetzt auch nicht an der "Echtzeitfähigkeit" des OS aufhängen, aber das Programm läuft später dann auf einem echzeitfähigen OS, da sollte es doch möglich sein mit der Sleep() Funktion Genauigkeiten unter 10-15ms zu bekommen oder irre ich mich da?



  • Sleep hat nun mal eine beschissene Auflösung, da wirst du wenig machen können. Wenn du Pech hast, dauert Sleep(1) einmal 5 ms und beim nächsten mal 15 ms oder noch länger. Ist auch von der Hardware abhängig und damit quasi auf jedem Rechner unterschiedlich.

    Du könntest es mal mit einem Waitable Timer Object versuchen, die sind in der Regel besser aufgelöst. Aber auch da gibts natürlich keine Garantien.



  • Zaus schrieb:

    ...

    *plonk*



  • volkard schrieb:

    Zaus schrieb:

    ...

    *plonk*

    Fantastisch, jetzt ist mir geholfen.



  • Der Fehler tritt immer noch auf. Das kann auch keine Schwankung sein. Ersten wäre die viel zu groß und 2. kann es sein, dass es 20 mal richtig läuft beim 21. dann zu lange brauch und von da an ist es dann IMMER zu langsam, dabei aber fast immer gleich langsam.



  • Ok, dann raten wir mal. Also ich setzt 1000€ auf die Zeilen 149-251. 🙄



  • Nach mehrfachen Suchen in dem Fred hier habe ich noch keine Zeile Code von einer
    zentral wichtigen Stelle gefunden.
    Was auch immer du tust, so hilft vielleicht eine Ausgabe in eine Datei z.B.
    einzelne Zeiten an bestimmten Stellen. Eine Minute unterschied die durch Sleeps zustande kommt? ... Müssen aber viele Sleeps sein 😃 du hast nicht zufällig eine
    if-Bedingung irgendwo drin mit Sleep(60000) in die er reinspringt?



  • Warum genau hast du die Sleep()-Aufrufe im Programm? Ich glaube dir fehlt für dein Vorhaben ganz einfach die Erfahrung in den Bereichen:






    MfG SideWinder



  • - Nein ich hab nirgendwo ein Sleep(60000) 🙄
    - Wozu brauch ich jetzt das Wissen über Echtzeitbetriebssysteme wenn das Programm gerade nur unter Windows7 läuft
    - Dass mir die Erfahrung beim Scheduling oder mit Profilern fehlt bestreite ich nicht, deshalb bitte ich ja auch um Hilfe.
    - Der Vorschlag ist nicht umsetzbar weil mit dem Programm Musik erzeugt wird und es nicht aktzeptabel ist wenn 2 Noten auf einmal 50-100ms näher aufeinander folgen als sie sollen nur um die Gesamtverzögerung auszugleichen, die Sleep Befehle dienen dazu den richtigen Abstand zwischen 2 Noten einzuhalten.
    - Ich hab keine Ahnung an was sowas grundsätzlich liegen könnte also bitte was für Codeteile soll ich posten? Ich bezweifel ja, dass dieser große Unterschied nur durch die Sleep-Befehle kommt aber ich weiss es nunmal nicht...
    - Am Einlesen der Dateien kann es nicht liegen, da ich alle Informationen vor dem eigentlich starten in einem vector speichere und dann während der Zeitmessung nur damit arbeite
    - Wie gesagt manchmal machts nen "Ruck" und das Programm ist fortan 20% langsamer, wenn ihr mir sagt welche Codeteile ich posten soll mach ich das gern.

    Gruß Zaus



  • Arbeitet das Programm mit threads? Wie sieht die Prozessorauslastung vor und nach dem "ruck" aus und wie verhält sich der Speicher?

    Alles so Dinge die verantwortlich sein _könnten_, das eingrenzen musst du übernehmen... Entsprechend mal kundig-googlen was ein Profiler ist und wie man ihn verwendet. Oder aber das Programm mal durchsteppen, und schaun, ob irgendwo was gemacht wird was du nicht willst, bzw. mal alle Schleifen und Bedingungen auf Richtigkeit prüfen, etc.



  • Zaus schrieb:

    - Der Vorschlag ist nicht umsetzbar weil mit dem Programm Musik erzeugt wird und es nicht aktzeptabel ist wenn 2 Noten auf einmal 50-100ms näher aufeinander folgen als sie sollen nur um die Gesamtverzögerung auszugleichen, die Sleep Befehle dienen dazu den richtigen Abstand zwischen 2 Noten einzuhalten.

    Ich empfehle nochmal das mit Waitable Timer Objects umzusetzen. Die haben in der Regel eine viel bessere Auflösung.

    Auf jeden Fall hat das mit C++ so ziemlich gar nichts mehr zu tun.


Log in to reply