Software-Experimente mit Linux

uli.brueggemann
Aktiver Hersteller
Beiträge: 4663
Registriert: 23.03.2009, 15:58
Wohnort: 33649
Kontaktdaten:

Beitrag von uli.brueggemann »

Hallo Frank,

da es hier beim improvefile um Dateien geht und ich das Programm dann selbst auch hrtfilecopy genannt habe war zumindest für mich der Rauswurf aller nicht benötigten Codezeilen eine klare Sache.

Das Problem bei der Vorgabe von bytespersec und loopspersec: spätestens mit den delayed blocks fängt man (z.B. ich) damit an die Werte zu ändern. Ob man dann dabei evtl. die Blockgrösse unpassend verändert bzw. ein unsinniges Timing realisiert (Aufruf ohne verbose) sieht man nicht. Man hat kein Gefühl ob es bei dem jeweils verwendeten Rechner gut passt.

Und ich finde nun Deine Ergebnisse mit den delayed blocks spannend. Was geht da vor sich?
Nach der Zeitmessung gibt das hrtfilecopy (v0.1) bei Dir eine Looptime von 2.200000 ms vor. Nun wird vor der Schleife die aktuelle Zeit erfasst. Und in der Schleife dann immer 2.2 ms als nächste Weckzeit dazuaddiert. Dass das Linux kein Echtzeitbetriebssystem ist wissen wir. Wir sollten aber annehmen können, dass das Sytem auf den Wecker hoffentlich pünktlich reagiert, gerne auch mit Verzögerung. Aber nicht früher!
Und nun wird aber auch vor dem Loop und ganz am Ende gemessen. hrtfilecopy zeigt die Zeit an, sie beträgt bei einer Stelle hinter dem Komma 32.7 s. Was auch anhand der Timingmessung abgeschätzt wurde. Die durchschnittliche Looptime am Ende ist 2.200696 ms, also 0.7 microsec länger. Bei 14851 chunks entspricht das 10 ms mehr an Laufzeit.

Wenn nun Deine Ausgabe anzeigt, dass von 14851 chunks 14851 delayed blocks verursachen, dann würde ich gern wissen bei wieviel Delay getriggert wird. Wenn dann lediglich angezeigt wird dass das Linux nicht punktgenau reagiert so ist das erwartbar und logisch.
Gib doch bitte noch an welche Zeilen Du da reinkopiert hast und wo. Dann kann ich mir das ebenfalls mal anschauen.

Grüsse
Uli

PS: hrtfilecopy zeigt die geschätzte Rechenzeit an Auch ein Vorteil, man muss nicht rätseln wann das Programm mit einem Kopiervorgang fertig ist.
Bild
Trinnov
Aktiver Hörer
Beiträge: 977
Registriert: 13.11.2009, 19:02

Beitrag von Trinnov »

Hallo Frank, hallo Uli,

ich halte das Ausgeben der beim Improven entstandenen delayed blocks als Indikator auch für sehr sinnvoll. Idealerweise sogar das prozentuale Verhältnis geschriebene Blocks zu delayed blocks am Ende der Ausführung. Dann muss man nicht die Trackgröße berücksichtigen beim bewerten.
Mir scheint das vermeiden von delayed blocks mit entscheidend für ein gutes Improve Ergebnis zu sein.
42% ist einfach viel zu viel. Ein sehr kleiner Prozentsatz scheint mit der Schlüssel für ein top Improve Ergebnis zu sein.

Nehme ich als Beispiel einen 100 MB großen Audio Track. Bei diesem sollen als Aufgabe nicht mehr als insgesamt 3 delayed blocks während des Schreibens des kompletten Tracks entstehen.
So handhaben wir das aktuell beim konfigurieren von Franks Software, die ein klasse Ergebnis liefert.

Ich bin wohl kein Mathematik Genie wie du Frank, aber ich habe mir das wie folgt berechnet. Ich hoffe das passt so.
100 MB = 104.857.600 Bytes (ein Beispiel Track mit 100 MB Größe)
/4096 = 25600 Blocks (ich rechne mal mit der 4K Ausrichtung ...)
( 3 / 25600) * 100 = 0,01172 % delayed blocks
Die Forderung von nicht mehr als 0,012% ist ein großer Unterschied zu den von Frank erwähnten 42%, die in Ulis Version aufgetreten sind.

Wenn Ulis Automatik optimiert werden kann, damit man diese delayed Blocks wirklich berücksichtigt und vermeidet, wäre es ein Weg.
Leider entstehen wie Frank es auch bereits erwähnt hat, die delayed Blocks tatsächlich sporadisch und dann manchmal gehäuft. Eine Messung / Erfassung für z.B. eine Sekunde wäre dann nicht zielführend. Somit keine einfache Aufgabe.


Viele Grüße
Horst
Bild
uli.brueggemann
Aktiver Hersteller
Beiträge: 4663
Registriert: 23.03.2009, 15:58
Wohnort: 33649
Kontaktdaten:

Beitrag von uli.brueggemann »

Hallo Horst,

wenn die vom mir anhand des Beispiels von Frank aufgezeigte Laufzeitverlängerung von ca. 10 ms bei 32.7 s Gesamtlaufzeit schädlich ist, dann gibt es diese Möglichkeit: es wird ja auch beim Beispiel angezeigt, dass die automatische Messung 1.63 ms je Loop braucht. Da wurde dann inkl. Sleep 2.2 ms verwendet. Nun kannst Du aber auch als Parameter --looptime=5000000 entsprechend 5ms vorgeben (bewusst extrem gewählt). Dann würde jeder Loop eben 3.37 ms schlafen, was das Doppelte der Rechenzeit wäre. hrtfilecopy macht dann eben keine Messung.
Man hat dann ja zumindest Anhaltswerte.

Und wenn das System trotzdem so arg daneben liegt, machen denn dann die Verwendung einer Nanosekunden!-Clock überhaupt Sinn?

Grüsse
Uli
Bild
Trinnov
Aktiver Hörer
Beiträge: 977
Registriert: 13.11.2009, 19:02

Beitrag von Trinnov »

Schwieriges Thema.
Wir wissen nicht genau warum es funktioniert, aber es funktioniert trotzdem.
Die Ohren entscheiden.

Gruß
Horst
Bild
nihil.sine.causa
Aktiver Hörer
Beiträge: 1507
Registriert: 28.07.2011, 12:31
Wohnort: Bonn

Beitrag von nihil.sine.causa »

Hallo zusammen,

ich muss gestehen, dass ich nicht alle neueren Beiträge hier gelesen habe, aber ich habe den Eindruck, dass ein weiterer Parameter nicht ausreichend berücksichtigt wird: Wir haben ja festgestellt (Horst war der erste), dass das mehrfache Improven hintereinander (also improvtes Schreiben auf das Zielmedium, anschließend Cache löschen, unmounten und neu mounten, Lesen der ersten Improvefile-Fassung und erneutes improvtes Schreiben) das Ergebnis besser macht als das einmalige Improven.

Die kausalen Zusammenhänge verstehe ich, wie gesagt, auch nicht, aber ich experimentiere etwas. Dabei improve ich Dateien in der Nacht, um sie am nächsten Tag zu hören.

Ich mache ein Beispiel: Speichermedium ist eine 8 GB große CF-Karte über SATA angebunden. Zunächst habe ich die Loops per second so eingestellt, dass ich wenige delayed blocks bekomme. Im Fall der CF-Karte sind es 4 loops per second.

Dann bestimme ich die bytes per second und bestimme damit die Geschwindigkeit des Verfahrens. Ich teste gerade 262144 bytes per second. Das ist auch eine 2er Potenz, insbesondere durch 4096 teilbar.

Und schließlich variiere ich die Zahl der Improvements hintereinander. Ich habe gute Erfahrungen damit gemacht, mehr als 3 auszuführen. Im Augenblick teste ich den Faktor NMAX = 5.

Mein Script, das auf Franks Software auf DietPi Linux aufsetzt, habe ich entsprechend angepasst. Ich kann loops per second, bytes per second sowie NMAX zu Beginn meines Scripts festlegen und dann läuft es automatisch mit diesen festen Werten. Bei guten Aufnahmen wird das sehr gut (Stabilität der Phantomschallquellen, Körperhaftigkeit der Transienten, räumliche Tiefe im Stereobild)!

Leerzeichen in den Musikdateien und Album-Namen akzeptiert das Script jetzt auch. Wer von euch daran Interesse hat, kann mir gerne eine PN senden.

Viele Grüße
Harald
Bild
Bernd Peter
Aktiver Hörer
Beiträge: 4007
Registriert: 04.05.2010, 19:37

Beitrag von Bernd Peter »

uli.brueggemann hat geschrieben: 31.12.2023, 14:50 Hallo Bernd-Peter,

wenn Du mal das hrtfilefopy antestest, dann wird Dir zumindest auch angezeigt was Dein Thinkpad T61 denn so erreichen kann. Es macht dabei Sinn das für eine chunksize von 4096 als auch 16384 anzuschauen.

Grüsse
Uli
Hallo Uli,

4096 = 2,336165 loop time (ms)
16384 = 2,802012 loop time (ms)

Es grüßt

Bernd Peter
Bild
Trinnov
Aktiver Hörer
Beiträge: 977
Registriert: 13.11.2009, 19:02

Beitrag von Trinnov »

Sehr ähnlich bei beiden Chunk Sizes.
Wird vielleicht an der "Automatik" liegen. Aber das weiß sicher Uli.

Viele Grüße
Horst
Bild
uli.brueggemann
Aktiver Hersteller
Beiträge: 4663
Registriert: 23.03.2009, 15:58
Wohnort: 33649
Kontaktdaten:

Beitrag von uli.brueggemann »

Nein,

das liegt daran, dass der Overhead zum Schreiben der Bytes (also das was im Linuxsystem selbst passiert) viel größer ist als das Schreiben der Bytes selbst.
Wenn man viele kleine Pakete packt braucht es zum Einwickeln ins Packpapier länger als bei einem größeren Paket.

Grüsse
Uli
Bild
Trinnov
Aktiver Hörer
Beiträge: 977
Registriert: 13.11.2009, 19:02

Beitrag von Trinnov »

ja, das weiß ich.
Aber ich hätte angenommen, dass bei Halbierung der Block Größe das Schreiben viel länger dauert.
Bei Bernd ist der Unterschied eher gering.

Grüße
Horst
Bild
uli.brueggemann
Aktiver Hersteller
Beiträge: 4663
Registriert: 23.03.2009, 15:58
Wohnort: 33649
Kontaktdaten:

Beitrag von uli.brueggemann »

Das tut es ja auch, es dauert länger.
16384 Bytes in einem Block werden in 2.8 ms weggeschrieben
16384 Bytes in vier Blöcken á 4096 Bytes dauern 4 * 2.3 ms = 9.2 ms

Grüsse
Uli
Bild
uli.brueggemann
Aktiver Hersteller
Beiträge: 4663
Registriert: 23.03.2009, 15:58
Wohnort: 33649
Kontaktdaten:

Beitrag von uli.brueggemann »

Mmh, ich stelle derzeit fest, dass wir da mit dem Hochpräzisions-Nanosekunden-Timer zwar eine nette Genauigkeit vortäuschen, in Wirklichkeit aber sowas wie ein Glücksrittertum betreiben.
Das Messen der Loops auf meinem NUC ergibt ein durchschnittliches Timing von 1.5 ms pro Loop. Nun kann ich da noch eine gewisse sleeptime dazuaddieren, z.B. 0.5 ms und lege damit eine looptime von 2 ms fest. Damit arbeitet dann auch der "Hochpräzisions"-Timer.
Nun messe ich beim realen Durchlauf dann zusätzlich die Zeit je Schleife (zusammenaddiert und gemittelt sieht dann alles ganz nett aus), merke mir aber die jeweils minimale und maximale Schleifenzeit. Da zeigt sich dann min = 0.95 ms und max = 11.8 ms. Das ist ja schon mal weit auseinander.
Ok, dann mache ich auf Sicherheit und definiere 12 ms als looptime. Das sind dann schon das 8-fache an Schlafenszeit im Vergleich zur benötigten Rechenzeit. Natürlich ist damit die Zeit je Track entsprechend um das 6-fache länger. Aber was soll's, wenn es dann passt.
Und was kommt raus: min = 1.2 ms und max = 32.3 ms !!!

Was nicht anderes heisst, als dass da das Betriebssystem ein Eigenleben führt, nicht kontrollierbar ist und man eben ein Zufallsergebnis bekommt.
Da kann man genausogut die Blöcke ohne Timer rausschreiben.

Vermutlich kommt ein Kommentar, dass man es eben trotzdem hört.

Grüsse
Uli

PS: das Herumspielen mit Prozessprioritäten (man kann das auch im Programm selbst vorgeben = sched_setpriority...) bringt übrigens genau ... nix, nada, null, niente.

PPS: beim Schreiben dieses Beitrags nochmal weiter rumgespielt. max = 159 ms !!! Da kann man auch ohne nanosleep werkeln.Was ja beim Aufruf das Programm suspendiert, also dem Linux Rechenzeit überlässt und man hoffen muss, dass man die nach Ablauf der sleeptime auch irgendwann wieder zurückbekommt.

PPPS: bufhrt wirft mir bei einem ersten Schnelltest ebenfalls Zeiten zwischen 3.3 ms und 20.3 ms raus (ohne delayed blocks)
Bild
Melomane
Aktiver Hörer
Beiträge: 3139
Registriert: 14.10.2011, 18:30

Beitrag von Melomane »

Hallo,

Was passiert denn, wenn man für die Arbeit eurer Progamme einen Prozessorkern reserviert und/oder mit der Priorisierung der Prozesse spielt? Oder ist das schon in den Programmen berücksichtigt?

Viele Grüße

Jochen
Bild
music is my escape
Aktiver Hörer
Beiträge: 1535
Registriert: 03.07.2012, 10:56
Wohnort: Leipzig

Beitrag von music is my escape »

uli.brueggemann hat geschrieben: 02.01.2024, 19:13
(…) Was nicht anderes heisst, als dass da das Betriebssystem ein Eigenleben führt, nicht kontrollierbar ist (…)
Hallo an alle;

Das erklärt natürlich so einige meiner leidvollen Erfahrungen bezüglich PC-Audio…
:mrgreen:

Freundliche Grüße,
Thomas
Bild
Buschel
Aktiver Hörer
Beiträge: 989
Registriert: 12.12.2013, 20:12
Wohnort: Raum Karlsruhe

Beitrag von Buschel »

Hallo in die Runde,
Melomane hat geschrieben: 02.01.2024, 19:19 Was passiert denn, wenn man für die Arbeit eurer Progamme einen Prozessorkern reserviert und/oder mit der Priorisierung der Prozesse spielt?
Interessant fände ich da eher den Einsatz eines realtime oder
zumindest low latency kernels. Damit dürften die zeitlichen Abweichungen zum gewünschten timing um einiges geringer ausfallen. Aber, offenbar ist die von einigen festgestellte Wirkung nicht von der Präzision der Taktung abhängig — obwohl das ja „böser“ Jitter ist.

Was ich mich immer wieder frage: Überschreibt der automatisch laufende RAM refresh nicht sowieso alle Speicherzellen neu bevor die Bits an USB- oder Ethernet-Controller weitergegeben werden? Macht es dann nicht eher Sinn, dass man versucht die Speicherzellen nach dem RAM refresh und so kurz wie möglich vor dem Weitergeben zu optimieren? Letztlich wäre das dann so etwas wie ein selbst implementierter RAM refresh. Das kann dann immer im RAM und ohne Umweg über einen Festspeicher passieren. Problematisch wird hier wieder das timing: besser nicht an den Daten arbeiten während diese ausgelesen/weitergegeben werden.

Grüße,
Andree
Bild
Trinnov
Aktiver Hörer
Beiträge: 977
Registriert: 13.11.2009, 19:02

Beitrag von Trinnov »

uli.brueggemann hat geschrieben: 02.01.2024, 19:13

... Vermutlich kommt ein Kommentar, dass man es eben trotzdem hört.

Grüsse
Uli

Ja, man kann es eben trotzdem hören. Dazu stehe ich.
Ich hatte da aber immer von Franks Software gesprochen.

Viele Grüße
Horst
Bild
Antworten