[markad] überarbeiteter Decoder

  • Das nenne ich Intuition!

    Jetzt läufts durch :]

    Anbei nochmal die Logs.

    Keine neuen compiler warnings.

    Wie man mit der OE-Toolchain ein Image baut mit dem man dann auf dem Zielsystem compiliert fehlt mir zur Zeit noch das Know How.

    Zudem ist die Gigablue Box mit nur 1GB Hauptspeicher dafür auch nicht sonderlich gut geeignet.

  • Das nenne ich Intuition!

    Gut formuliert, mit Wissen hatte das nichts zu tun, das war reines Bauchgefühl.


    Das werde ich so aber nicht in die normale Version übernehmen können. Ich habe das jetzt über Compiler Directive auf den GCC Version 7 beschränkt. Bitte nochmals den finalen Patch mit dem aktuellen Stand aus Branch push_back testen, ob die Directive bei dir zieht. Nach deinem OK wird es eine neue Version geben, da ich Segfault Fixe immer möglichst zeitnah tagge.

  • War das eigentlich die einzige Stelle wo das push_back im source verwendet wird?

    Nein, aber scheinbar die einzige Stelle wo es bei dir crashed.



    Das Directive greift nicht

    Das sind wohl noch zwei Fehler unterwegs:


    1. Hast du einen git pull und einen make clean gemacht ? Das Makefile hat sich geändert und ich sehe in deinen Log nicht die neue Meldung aus dem Makefile. Da müsste eine Zeile kommen: "compiler version: ..."


    2. Ich habe die GCC Version von 7 auf 9 geändert, bitte nochmals aktualisieren und neu bauen.

  • Sorry hab beim letzten Hochladen eine alte Log-Datei erwischt.

    Jetzt greift das Directive.

    Trotzdem schon erstaunlich der Fehler beim push_back. Da fragt man sich warum überhaupt ein Programm auf der Box richtig läuft. :/

    Der derzeitige Workaround ist vermutlich nicht sehr effizient. Schaut man sich das vorherige Log mal an wo noch mehr debug output kam

    so wird da vermutlich bei dem Teststream über 5000 mal der vector reallokiert.

  • so wird da vermutlich bei dem Teststream über 5000 mal der vector reallokiert.

    Ja, aber so arbeiten Vektoren eben. Das macht genau so auch der push_back, aber eben intern. Darum bin ich ja auf die Idee gekommen, das Problem in der Lib zu umgehen, indem ich vorher selbst den Speicher vom Vektor groß genug für das nächste Element zu machen.


    Jetzt greift das Directive.

    OK, dann übernehme ich das so in die nächste Version.

  • Anbei eine andere Patchvariante als Workaround für den crash.

    Das bringt auf meiner Box noch ca. 2% bessere Laufzeit.

    Den kannst du eventuell auch ohne Compiler-Abhängigkeit einbauen da auch auf anderen Plattformen vermutlich nützlich.

  • IndexVector: Das wundert mich, dass das geht, weil die allokiert ja nur die ersten 1000 Elemente vor. Und damit sparst du dann die 2% Laufzeit.

    Das Risiko ist mir hier zu hoch, dass es mit irgendeinem anderen Video wieder crashed. Was passiert nach dem 1000sten Element ? Gibt es einen nächsten Wert, der wieder Probleme macht ? Das weiß keiner. Die beste Lösung, die stdlibs deiner Build Umgebung passend zum Compiler zu bekommen.


    ptsRing: Der Vector hat eine konstante Größe, da macht das Sinn.

  • Die Version 3.0.24 ist auf vdr-plugin-markad verfügbar. Sie enthält die o.g. Fix gegen einen Segfault auf ARM Systeme. thx durchflieger

    Code
    - fix segfault in stdlib after vector push_back on arm systems with gcc9
    - pre alloc memory of ptsRing buffer
    - some minor bug fixes and optimizations, see git
  • IndexVector: Das wundert mich, dass das geht, weil die allokiert ja nur die ersten 1000 Elemente vor. Und damit sparst du dann die 2% Laufzeit.

    Das Risiko ist mir hier zu hoch, dass es mit irgendeinem anderen Video wieder crashed. Was passiert nach dem 1000sten Element ? Gibt es einen nächsten Wert, der wieder Probleme macht ? Das weiß keiner. Die beste Lösung, die stdlibs deiner Build Umgebung passend zum Compiler zu bekommen.


    ptsRing: Der Vector hat eine konstante Größe, da macht das Sinn.

    Mein Testvideo benötigt ja über 5000 Einträge.

    Das push_back wird dabei mindestens 5 mal reallokieren müssen was offenbar nicht zu einem crash führt.

    Bezüglich der wirklichen Ursache auf meinen System stochern wir deshalb immer noch im Nebel.

    Unabhängig davon macht das reserve() am Anfang gerade auf indexVector Sinn weil viele Einträge und nur wenige auf ptsRing.

    Wie cppreference.com zum vector schreibt:


    Code
    Notes
    
    Correctly using reserve() can prevent unnecessary reallocations, but inappropriate uses of reserve() (for instance, calling it before every push_back() call) may actually increase the number of reallocations (by causing the capacity to grow linearly rather than exponentially) and result in increased computational complexity and decreased performance. For example, a function that receives an arbitrary vector by reference and appends elements to it should usually not call reserve() on the vector, since it does not know of the vector's usage characteristics.

    folgt dein Workaround dieser Empfehlung nicht.


    Aber du kannst es auch so lassen. Die 2% tuen nicht weh.

    Vielen Dank noch mal für deine Unterstützung!

  • Deine Argumente überzeugen mich. Aber zum Start mal 1000 Elemente zu allokieren und dann doch wieder einzeln ist auch nur eine halbe Lösung.

    Ich schaue mal, ob ich da für die nächste Version nochmals was optimieren kann. Ideal wäre, wenn ich vor dem ersten Element abschätzen könnte, wie viele ich brauche um dann gleich alle allokieren. Wenn nicht, dann in z.B. 1000er Blöcken.

    Das push_back wird dabei mindestens 5 mal reallokieren müssen was offenbar nicht zu einem crash führt.

    Nein, bei deinem Code würde er 1 x 1000 und dann 4000 x 1 Element allokieren. Und genau das gefällt mir nicht.

  • Deine Argumente überzeugen mich. Aber zum Start mal 1000 Elemente zu allokieren und dann doch wieder einzeln ist auch nur eine halbe Lösung.

    Ich schaue mal, ob ich da für die nächste Version nochmals was optimieren kann. Ideal wäre, wenn ich vor dem ersten Element abschätzen könnte, wie viele ich brauche um dann gleich alle allokieren. Wenn nicht, dann in z.B. 1000er Blöcken.

    Nein, bei deinem Code würde er 1 x 1000 und dann 4000 x 1 Element allokieren. Und genau das gefällt mir nicht.

    Ja da hast du vermutlich Recht das push_back weiterhin nur für das aktuelle Element neuen Speicher anfordert.

    Ich hab den Test mal mit 10000 reservierten Elementen am Anfang durchgeführt mit dem Ergebnis das die Laufzeit wieder schlechter wird! :wow

    Auf meinen System hier zu messen scheint keine gute Idee zu sein.

  • durchflieger

    Ich habe jetzt eine Optimierung drin: Es werden grundsätzlich 1000er Blocke allokiert.

    Teste bitte mal Branch master gegen V03.

    Bei mir hat es keinen erkennbaren Performance Vorteil gebracht. Ist für mich aber auch schwer zu testen, das bei mit viele Container auf dem gleichen Host laufen und somit ich nie eine reproduzierbare Systemlast habe.

    Aber egal, auch wenn es nichts bringt, komme ich so ohne Sonderbehandlung für deine Buildumgebung aus. Und alleine das ist mir viel Wert.

  • > Für das überspringen der von markad erzeugten Schnittmarken, bei der Wiedergabe von Aufnahmen, empfiehlt sich der jumpplay-patch.

    Dieser Patch ist doch inzwischen Teil von VDR (?)

    Client1: ASUS P5QC, Dual Core 3G, Cine S2, Ext. Board von TBE, Xubuntu 20.04, VDR 2.6x

    Client2: RPI3

    Server: RPI4, Sundtek SkyTV Dual 2x

  • Danke für den Hinweis. Ich habe das aus dem ursprünglichen Text ungeprüft übernommen, da ich selbst kein VDR Frontend nutze. Ich habe es aus dem Wiki raus genommen.

  • Es gibt jetzt auch ein Wiki zu markad im Git.

    Eine Frage dazu: Was muss ich einstellen, damit möglichst wenig Systemlast entsteht?
    --ioprio=2,7 ?

    Was ist mit Leerlauf gemeint. Läuft dann markad nicht wenn vdr was aufnimmt oder abspielt?

  • Ja, die Beschreibung von diesem Punkt ist nicht nur unverständlich, sondern auch in Teilen falsch, danke für den Hinweis.

    Neuer Text:

    Code
    I/O-Priorität vom markad Prozess
    class 1 = Echtzeit (level 0-7, default level: 4)
    class 2 = ausgewogen (level 0-7, default level: 4)
    class 3 = Leerlauf (hier gibt es keinen Level)
    markad default ist class = 3, also Leerlauf. Die ausgewähle I/O Priorität kann auf dem System nur wirken, wenn ein Diskscheduler verwendet wird, der auch I/O Prioritäten unterstützt (zum Beispiel BFQ). Infos, wie man überprüfen kann welcher Scheduler verwendet wird und wie man diesen ändern kann, gibt es in den Wikis der verwendeten Distribution (zum Beispiel Ubuntu IOSchedulers Wiki). Dieser Wert sollte nicht erhöht werden, da markad sehr I/O intensiv ist und somit andere Anwenung auf dem System beeinträchtigen kann.


    Was ist mit Leerlauf gemeint. Läuft dann markad nicht wenn vdr was aufnimmt oder abspielt?

    Nein, das heißt nur, dass der markad I/O erst dann bearbeitet wird, wenn kein anderer Prozess auf dem System gerade einen I/O machen will. Diese Einstellung ist wie (jetzt) im Wiki beschrieben dringend empfohlen, weil es sonst dazu führen kann, dass, wenn auf dem VDR mehrere HD (oder gar UHD) Aufnahmen gleichzeitig laufen, er die Daten nicht immer schnell genug weg schreiben kann. Das kann man dann im System sehen ("ring buffer overflow").

    markad läuft dann trotzdem, aber eben ein klein wenig langsamer.

  • Danke für die Erklärung. Bei mir laufen öfters mehrere Aufnahmen und gleichzeitig schaue ich aufgenommenes Material an.

    Die ausgewähle I/O Priorität kann auf dem System nur wirken, wenn ein Diskscheduler verwendet wird, der auch I/O Prioritäten unterstützt (zum Beispiel BFQ).

    Kann das markad prüfen und eventuell ins Log schreiben?

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!