[C++] Daten kopieren - Optimierung

Programmiersprachen, APIs, Bibliotheken, Open Source Engines, Debugging, Quellcode Fehler und alles was mit praktischer Programmierung zu tun hat.
Antworten
keepcoding
Beiträge: 30
Registriert: 28.11.2003, 17:19
Kontaktdaten:

[C++] Daten kopieren - Optimierung

Beitrag von keepcoding »

Ich möchte möglichst effizient Daten auf der Festplatte herumkopieren. Dabei wird es sich hauptsächlich um Dateien im Gigabyte-Bereich handeln. Wie kopiere ich nun am schnellsten Daten von einem Ort an einen anderen auf der Festplatte?
Bisher hab ich das einfach mittels fstream gelöst, was im Durchschnitt jedoch sogar langsamer ist als die Windowseigene Kopierfunktion (CopyFile).
Meine Fragen:

a) Gibt es dafür schnellere Varianten? Ist vielleicht sogar fread / fwrite schneller?
b) Welche Puffergrösse ist am "freundlichsten" für Festplatten? Spielt das überhaupt eine Rolle? Ist 1 Megabyte genauso gut wie 1 Mebibyte?
c) Macht multi-threaded kopieren (ein Thread liest, ein anderer schreibt gleichzeitig) Sinn oder wird dann das Problem bloss auf die DMA ausgelagert? Ich würde meinen, dass besonders dann, wenn von einer auf eine andere Festplatte kopiert wird, dies sinnvoll sein könnte.
Benutzeravatar
Krishty
Establishment
Beiträge: 8238
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [C++] Daten kopieren - Optimierung

Beitrag von Krishty »

keepcoding hat geschrieben:a) Gibt es dafür schnellere Varianten? Ist vielleicht sogar fread / fwrite schneller?
::std::fstream, fwrite und alle anderen Funktionen greifen intern auch nur auf die WinAPI zurück. Schneller als CopyFile wird es praktisch nicht werden – die Funktion benutzt jeder Windows-User seit 15 Jahren zig Mal täglich wenn er im Dateixplorer arbeitet; ich glaube nicht, dass MS die unoptimiert gelassen hat … auch liegt bei mir persönlich die in CopyFile() angezeigte Geschwindigkeit immer ziemlich nah am physischen Maximum der Festplatte – das einzige, was bremst, ist der Virenscan …
keepcoding hat geschrieben:b) Welche Puffergrösse ist am "freundlichsten" für Festplatten? Spielt das überhaupt eine Rolle? Ist 1 Megabyte genauso gut wie 1 Mebibyte?
Wenn mehr gepuffert werden kann, braucht der Schreibkopf nicht so oft zwischen Lese- und Schreibposition hin- und herzspringen. Ein MB ist dann 4,8576 % schlechter als ein MiB.
keepcoding hat geschrieben:c) Macht multi-threaded kopieren (ein Thread liest, ein anderer schreibt gleichzeitig) Sinn oder wird dann das Problem bloss auf die DMA ausgelagert? Ich würde meinen, dass besonders dann, wenn von einer auf eine andere Festplatte kopiert wird, dies sinnvoll sein könnte.
Am schnellsten wäre es, wenn du die Datei komplett in den RAM liest und von dort wieder auf die Platte schreibst, ohne Multi-Threading. Dann muss der Lese-/Schreibkopf im Idealfall nur einmal springen. Also den freien physischen Speicher ermitteln, soviel allokieren, füllen, und dann wieder zurückschreiben. Für große Dateien in einer Schleife. Weniger allokieren ist weniger effizient, mehr allokieren ist noch weniger effizient weil dann Auslagerung beginnt. Wenn dein Programm abgebrochen wird oder ein Stromausfall eintritt, hat der User eine kaputte Datei auf der Platte – also hier eine temporäre Datei anlegen und erst nach Erfolg an die Zielposition verschieben. Die temporäre Datei muss die finale Größe haben bevor sie gefüllt wird, damit das Dateisystem nicht mitten im Schreibvorgang neue Sektoren allokieren muss. Und denk daran, dass der User währenddessen nicht viel am Rechner wird machen können, weil sowohl RAM als auch HDD voll ausgelastet sein werden. (Das meinte ich ganz oben mit „praktisch“ – wenn du es optimal haben willst, kommt ein Rattenschwanz Herausforderungen auf dich zu).

Am sinnvollsten hingegen wäre ::CopyFile() – wenn sobald SSDs etabliert sind, war nämlich der gesamte Aufwand für den Popo.

Gruß, Ky
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Despotist
Establishment
Beiträge: 394
Registriert: 19.02.2008, 16:33

Re: [C++] Daten kopieren - Optimierung

Beitrag von Despotist »

Krishty hat geschrieben: Dann muss der Lese-/Schreibkopf im Idealfall nur einmal springen.
Man bedenke dass die normale Festplatte nicht nur einen dieser Köpfe hat. Sind meist mehrere Scheiben jede mit eigenem Kopf.
Bei einer SSD-Festplatte hättest du diese Probleme nicht.
Musst du die Daten wirklich kopieren (behälst du sie an alter Position)? Wenn du sie verschieben willst wird nur der Eintrag in der File-Table geändert und die Datei nicht angefasst. Vielleicht reicht das ja.
keepcoding
Beiträge: 30
Registriert: 28.11.2003, 17:19
Kontaktdaten:

Re: [C++] Daten kopieren - Optimierung

Beitrag von keepcoding »

@Despotist: Ja, kopieren. Für das Verschieben von Dateien verwende ich die MoveFile-Funktion.

@Krishty: danke für die Tipps! Werd mal sehen, ob ich nun doch CopyFileEx verwenden soll anstelle von einer eigenen Funktion. Auch deshalb, weil ich gerade gesehen habe, dass CopyFileEx auch Resuming unterstützt...
Antworten