Idee gesucht....
Idee gesucht....
Hallo Zusammen,
hatte letztens die Idee, mittels eines scripts das Zippen von grossen Dateien
auf mehrere Prozessoren zu verteilen.
Nur so aus Spass...
Seitdem versuche ich das Script noch weiter zu beschleunigen.
Im Moment ist es so:
Die Datei wird mittels split aufgeteilt, fuer jeden Prozessor ein Stueck.
Dann wird fuer jeden Prozessor ein Hintergrund-Prozess gestartet, der einen
diser Dateistuecke zippt.
Wenn alle fertig sind, werden die Zip-Stuecke zusammen gebracht.
Funktioniert fuer Dateien bis ~1GB eigentlich ganz gut.
Werden die Dateien aber groesser, dauert es irgendwann uebermaessig lange
bis alleine mal split durchgelaufen ist.
Dann kam ich auf die Idee in jedem Hintergrund-Prozess mittels dd direkt aus
der Quelldatei zu lesen.
Aber das war viel langsamer, da gzip sich die Rechenpower mit dd teilen musste.
Hat einer von Euch eine Idee wie man das noch loesen koennte?
Wie schon geschrieben, nur so zum Spass am scripten. Ich suche keine
Fertigloesung ala: Das Programm xy-z kann das doch schon...
Viele Gruesse,
heinz
hatte letztens die Idee, mittels eines scripts das Zippen von grossen Dateien
auf mehrere Prozessoren zu verteilen.
Nur so aus Spass...
Seitdem versuche ich das Script noch weiter zu beschleunigen.
Im Moment ist es so:
Die Datei wird mittels split aufgeteilt, fuer jeden Prozessor ein Stueck.
Dann wird fuer jeden Prozessor ein Hintergrund-Prozess gestartet, der einen
diser Dateistuecke zippt.
Wenn alle fertig sind, werden die Zip-Stuecke zusammen gebracht.
Funktioniert fuer Dateien bis ~1GB eigentlich ganz gut.
Werden die Dateien aber groesser, dauert es irgendwann uebermaessig lange
bis alleine mal split durchgelaufen ist.
Dann kam ich auf die Idee in jedem Hintergrund-Prozess mittels dd direkt aus
der Quelldatei zu lesen.
Aber das war viel langsamer, da gzip sich die Rechenpower mit dd teilen musste.
Hat einer von Euch eine Idee wie man das noch loesen koennte?
Wie schon geschrieben, nur so zum Spass am scripten. Ich suche keine
Fertigloesung ala: Das Programm xy-z kann das doch schon...
Viele Gruesse,
heinz
Re: Idee gesucht....
Es dürfte eher am Einlesen liegen.
Liest Du mehrere Stücke einer Datei gleichzeitig, so muß der Lesekopf hin- und herspringen,
das dürfte den Prozeß eher verlangsamen.
Meine hdd ~ 100MB/s,
einen /dev/zero-Stream wird mit ~ 100MB/s komprimiert.
Solange die Festplatte nicht sehr viel schneller liefert, als die CPU komprimiert,
verlangsamt ein Splitten/Parallelisieren den Vorgang nur.
--------------------------------------------------------------------
Okay, wenn es wirklich was zu tun gibt wird das zippen doch erheblich langsamer.
Aber dennoch, das muß ja auch geschrieben werden ~ verringert die Leserate,
und Random-Daten werden auch nicht komprimiert, zippen also irgendwo ~ Lesen/Schreiben.
Mir würde ein Parallelisieren also nichts oder wenig bringen.
Liest Du mehrere Stücke einer Datei gleichzeitig, so muß der Lesekopf hin- und herspringen,
das dürfte den Prozeß eher verlangsamen.
Meine hdd ~ 100MB/s,
einen /dev/zero-Stream wird mit ~ 100MB/s komprimiert.
Solange die Festplatte nicht sehr viel schneller liefert, als die CPU komprimiert,
verlangsamt ein Splitten/Parallelisieren den Vorgang nur.
Code: Alles auswählen
$ dd if=/dev/zero bs=1M count=1000 | gzip -c > /dev/null
1000+0 Datensätze ein
1000+0 Datensätze aus
1048576000 Bytes (1,0 GB) kopiert, 10,6017 s, 98,9 MB/s
$ dd if=/dev/zero bs=1M count=1000 | gzip -1 -c > /dev/null
1000+0 Datensätze ein
1000+0 Datensätze aus
1048576000 Bytes (1,0 GB) kopiert, 7,24732 s, 145 MB/s
# hdparm -tT /dev/sdb
/dev/sdb:
Timing cached reads: 3506 MB in 2.00 seconds = 1754.76 MB/sec
Timing buffered disk reads: 394 MB in 3.00 seconds = 131.23 MB/sec
--------------------------------------------------------------------
Okay, wenn es wirklich was zu tun gibt
Code: Alles auswählen
# dd bs=1M if=/dev/shm/urandom | gzip -c > /dev/null
512+0 records in
512+0 records out
536870912 bytes (537 MB) copied, 21.8989 s, 24.5 MB/s
# dd bs=1M if=/dev/shm/urandom | gzip -1 -c > /dev/null
512+0 records in
512+0 records out
536870912 bytes (537 MB) copied, 20.1811 s, 26.6 MB/s
Aber dennoch, das muß ja auch geschrieben werden ~ verringert die Leserate,
und Random-Daten werden auch nicht komprimiert, zippen also irgendwo ~ Lesen/Schreiben.
Mir würde ein Parallelisieren also nichts oder wenig bringen.
Zuletzt geändert von rendegast am 10.09.2015 20:24:41, insgesamt 1-mal geändert.
mfg rendegast
-----------------------
Viel Eifer, viel Irrtum; weniger Eifer, weniger Irrtum; kein Eifer, kein Irrtum.
(Lin Yutang "Moment in Peking")
-----------------------
Viel Eifer, viel Irrtum; weniger Eifer, weniger Irrtum; kein Eifer, kein Irrtum.
(Lin Yutang "Moment in Peking")
Re: Idee gesucht....
Heinz warum nutzt du pbzip2 oder pxz nicht??
Debian-Nutzer
ZABBIX Certified Specialist
ZABBIX Certified Specialist
Re: Idee gesucht....
Das ist auf jeden Fall ein Teil der Erklärung.rendegast hat geschrieben:Es dürfte eher am Einlesen liegen.
Liest Du mehrere Stücke einer Datei gleichzeitig, so muß der Lesekopf hin- und herspringen,
das dürfte den Prozeß eher verlangsamen.[/code]
Wenn man split vorweg laufen läßt, werden die Dateiteile zunächst in den Cache geschrieben (der Linuxkern verwendet praktisch den kompletten freien Hauptspeicher für Cacheoperationen). Je nach RAM-Größe können alle Dateiteile, die split produziert, komplett ins RAM (also Cache) passen. Die einzelnen zip-Prozesse können dann extrem schnell die Dateiteile lesen, Cache-Zugriffe sind rund 100 mal schneller als Plattenzugriffe.
Steigt die ursprüngliche Dateigröße über die RAM-Größe, reicht der Cache nicht mehr aus und es wird wohl oder über über die Festplatte gearbeitet, was die überproportionale Verlangsamung ab 1GB Dateigröße erklärt. Bei meinem Rechner mit 8GB RAM sind praktisch ständig 7GB frei, so daß bei mir erst am 3.5 GB Dateigröße eine überproportionale Verlangsamung festzustellen wäre. Warum 3.5 GB? Nun, in den freien 7GB RAM werden die 3.5GB der Ausgangsdatei und die 3.5GB des Spiltresultats zwischengespeichert.
Läßt man split weg und verwendet direkt dd, um die Dateiteile ohne Cache direkt zu lesen, verlangsamen nicht nur die Kopfbewegungen den Lesevorgang, sondern auch das Fehlen des Caches. Die CPU-Last, die dd erzeugt, ist allerdings völlig vernachlässigbar, das bremst praktisch nicht.
Man könnte, um den Vorgang zu beschleunigen, die Urspungsdatei einmal komplett durchlesen lassen, was den Cache vorbefüllen würde. Da keine Dateiteile benötigt werden, passen so auch doppelt so große Ausgangsdateien in den Cache, so daß sie die Datengrenze bei meine 8GB-System auf rund 7GB erhöhen ließe, bevor der Cache voll läuft. Beim System des OP sollte sich die Grenze auf mindestens 2GB erhöhen lassen.
Wie kann man nun den Cache vorbefüllen?
Nun, einfach einmal durchlesen, z.B. mit
dd if=Ausgangsdatei of=/dev/null bs=10485760
Danach kann man direkt mit dd, wie der OP vorgeschlagen hat, auf die Dateiteile zugreifen. Da hier dann über den Cache gearbeitet werden kann, fallen keine Kopfbewegungen an und der lineare Datendurchsatz aus dem RAM liegt bei 10GB/s statt 100MB/s von der Platte.
-
- Beiträge: 827
- Registriert: 26.05.2008 12:04:54
- Lizenz eigener Beiträge: GNU Free Documentation License
- Wohnort: Nörten-Hardenberg
-
Kontaktdaten:
Re: Idee gesucht....
Je nachdem wie groß deine Dateien und wieviele es sind, könntest du ggf. direkt in einer RAM Disk arbeiten.
Dort kannst du dann deine ZIP Datei erstellen lasse und schiebst die am Ende einfach mit einem mv in deinen Ordner auf der Platte.
Abhängig von der Menge der Archive und deren größe könntest du quasi alles in der RAM Disk erstellen, was die Platte dann auch beim lesen nicht behindern dürfte.
Erst wenn alles durch ist müsste er die Daten einmal schreiben.
So solltest du die Platte im Idealfall ohne gleichzeitge Lese- und Schreibzugriffe nutzen können.
Sollte im Idealfall auch etwas Performance bringen.
Martin
Dort kannst du dann deine ZIP Datei erstellen lasse und schiebst die am Ende einfach mit einem mv in deinen Ordner auf der Platte.
Abhängig von der Menge der Archive und deren größe könntest du quasi alles in der RAM Disk erstellen, was die Platte dann auch beim lesen nicht behindern dürfte.
Erst wenn alles durch ist müsste er die Daten einmal schreiben.
So solltest du die Platte im Idealfall ohne gleichzeitge Lese- und Schreibzugriffe nutzen können.
Sollte im Idealfall auch etwas Performance bringen.
Martin
Es gibt keine if Schleife -> http://www.if-schleife.de/
Ansonsten GPL/GNU/Linux/Debian/Free Software 4 Ever
Ansonsten GPL/GNU/Linux/Debian/Free Software 4 Ever
Re: Idee gesucht....
Colttt hat geschrieben:Heinz warum nutzt du pbzip2 oder pxz nicht??
OK?heinz hat geschrieben:Wie schon geschrieben, nur so zum Spass am scripten. Ich suche keine
Fertigloesung ala: Das Programm xy-z kann das doch schon...
Jesus saves. Buddha does incremental backups.
Windows ist doof, Linux funktioniert nicht • Don't break debian! • Wie man widerspricht
Windows ist doof, Linux funktioniert nicht • Don't break debian! • Wie man widerspricht
Re: Idee gesucht....
Erstmal Danke fuer Eure Antworten.
So wie ich das alles hier lese, sind wohl die Plattenzugriffe einer der Haupttaeter.
Das mit dem Cache oder der Ramdisk ist ne gute Idee aber ich meine wirklich grosse Dateien.
Gepackt werden einzelne Dateien mit bis zu 30 GB.
Um die Quelldatei nur einmal zu lesen koennte man doch mit:
die Quelldatei z.B. in 3 "Datenstroeme" aufteilen
und in den Hintergrundprozessen dann mit:
lesen.
Koennte das gehen?
Wie verhaelt sich denn cat, wenn an den fifos unterschiedlich schnell gelesen wird? Sollte man buffern?
Fragen ueber Fragen... Ich werds wohl ausprobieren.
Melde mich wieder.
Weitere Anregungen sehr willkommen...
Gruss,
heinz
So wie ich das alles hier lese, sind wohl die Plattenzugriffe einer der Haupttaeter.
Das mit dem Cache oder der Ramdisk ist ne gute Idee aber ich meine wirklich grosse Dateien.
Gepackt werden einzelne Dateien mit bis zu 30 GB.
Um die Quelldatei nur einmal zu lesen koennte man doch mit:
Code: Alles auswählen
cat $quelldatei | tee ./fifo_1 | tee ./fifo_2 >./fifo_3
und in den Hintergrundprozessen dann mit:
Code: Alles auswählen
dd skip=... count=... if=./fifo...
Koennte das gehen?
Wie verhaelt sich denn cat, wenn an den fifos unterschiedlich schnell gelesen wird? Sollte man buffern?
Fragen ueber Fragen... Ich werds wohl ausprobieren.
Melde mich wieder.
Weitere Anregungen sehr willkommen...
Gruss,
heinz
Re: Idee gesucht....
Man könnte noch für möglichst viel freien Cache sorgen.
D.h. folgendes zu Erst im Hintergrund starten:
Wobei das sync im Fall der Fälle auch ewig dauern kann und wieder für Bewegung des Festplattenkopfes sorgt.
D.h. folgendes zu Erst im Hintergrund starten:
Code: Alles auswählen
(sync ; echo "3" | sudo tee /proc/sys/vm/drop_caches >/dev/null) &
Re: Idee gesucht....
Habs ausprobiert.
Ein:
Erzeugt 3 gezippte Kopien der Quelldatei. Soweit so gut...
Sobald ich aber versuche den dd ins Spiel zu bringen klappt es nicht mehr.
Dateigroesse = 563MB = 196782764
Screiben wieder wie oben mit cat.
Lesen mit:
Was passiert:
Egal in welcher Reihenfolge die "dds" und cat gestartet werden.
Alle drei "dds" und der schreibende cat sind der Meinung die Arbeit sei erledigt, wenn der erste dd seinen count= erreicht hat.
Ergebnis:
Selbst ohne Abbruch wuerde der zweite dd erst anfangen,
wenn der erste "durch" ist.
Schade, da laesst sich wohl mit "Bordmitteln" nicht viel Optimieren.
Wenn noch einer eine zuendende Idee hat, bitte, gerne...
Ansonsten, vielen Dank fuer Eure Vorschlaege.
Viele Gruesse,
heinz
Ein:
und dann 3 mal:cat ./quelldatei |tee ./fifo1 |tee ./fifo2 >./fifo3
Code: Alles auswählen
cat ./fifo[1-3] |gzip >./[1-3].gz
Sobald ich aber versuche den dd ins Spiel zu bringen klappt es nicht mehr.
Dateigroesse = 563MB = 196782764
Screiben wieder wie oben mit cat.
Lesen mit:
Code: Alles auswählen
dd if=./fifo1 of=./1.bin skip= 0 bs=1 count=196782764
dd if=./fifo2 of=./2.bin skip=196782764 bs=1 count=196782764
dd if=./fifo3 of=./3.bin skip=393565528 bs=1 count=196782764
Egal in welcher Reihenfolge die "dds" und cat gestartet werden.
Alle drei "dds" und der schreibende cat sind der Meinung die Arbeit sei erledigt, wenn der erste dd seinen count= erreicht hat.
Ergebnis:
- 188M 1.bin
70K 2.bin
0 3.bin
Selbst ohne Abbruch wuerde der zweite dd erst anfangen,
wenn der erste "durch" ist.
Schade, da laesst sich wohl mit "Bordmitteln" nicht viel Optimieren.
Wenn noch einer eine zuendende Idee hat, bitte, gerne...
Ansonsten, vielen Dank fuer Eure Vorschlaege.
Viele Gruesse,
heinz