Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   ReadFile und WriteFile durch Threads optmieren (https://www.delphipraxis.net/194712-readfile-und-writefile-durch-threads-optmieren.html)

LTE5 26. Dez 2017 17:34

ReadFile und WriteFile durch Threads optmieren
 
Ich benutze schon immer ReadFile und WriteFile, um eine Datei zu kopieren.
So kopiere ich 2 10 GB Dateien von einer SSD innerhalb von 4 Minuten und 25 Sekunden. Unstoppable Copier braucht dafür 4 Minuten und 10 Sekunden.
Das sind Durchschnittswerte nachdem ich etliche Tests durchlaufen habe. Der Windows-File-Cache war natürlich weg!

Ist es möglich eine Kopierfunktion mit ReadFile und WriteFile so zu trennen, dass ReadFile und WriteFile je in einem Thread laufen?
ReadFile befüllt eine Art Liste von der ich noch absolut keine Ahnung habe wie das sein soll, aus der sich WriteFile dann bedient.

Oder ist ganz davon abzuraten?

dummzeuch 26. Dez 2017 17:53

AW: ReadFile und WriteFile durch Threads optmieren
 
Theoretisch kann ReadFile Daten in einen Buffer lesen, aus dem WriteFile dann schreibt. Sowas wie eine Queue von x*4096 Bytes großen Buffern würde sich anbieten.

Aber ob das wirklich schneller ist, kann ich nicht sagen.

Zacherl 26. Dez 2017 17:58

AW: ReadFile und WriteFile durch Threads optmieren
 
Zitat:

Zitat von LTE5 (Beitrag 1389681)
Ich benutze schon immer ReadFile und WriteFile, um eine Datei zu kopieren.

Warum verwendest du nicht einfach die entsprechende WindowsAPI anstelle dir mit ReadFile/WriteFile manuell einen abzubrechen? Dort wären solche Optimierungen im Zweifelsfalle nämlich auch schon von Haus aus vorhanden.

LTE5 26. Dez 2017 18:01

AW: ReadFile und WriteFile durch Threads optmieren
 
Weil so kann ich
auf Abbrechen reagieren
habe immer die bereits kopierten Bytes und die Bytes die im letzten Durchgang kopiert wurden in Variablen
und ich kann meinen eigenen Buffer setzen

Wie würde man denn das hier mit der WindowsAPI umschreiben? http://www.delphipraxis.net/192758-f...im-thread.html

Uwe Raabe 26. Dez 2017 18:16

AW: ReadFile und WriteFile durch Threads optmieren
 
Zitat:

Zitat von Zacherl (Beitrag 1389684)
Warum verwendest du nicht einfach die entsprechende WindowsAPI anstelle dir mit ReadFile/WriteFile manuell einen abzubrechen? Dort wären solche Optimierungen im Zweifelsfalle nämlich auch schon von Haus aus vorhanden.

Ich weiß zwar nicht, ob das noch relevant ist, aber da ist eventuell Vorsicht geboten: Copying large files on Windows

LTE5 26. Dez 2017 18:19

AW: ReadFile und WriteFile durch Threads optmieren
 
Verstehe ich das richtig, dass, angenommen der Fall Program X wird von Windows XP bis 10 verwendet, ReadFile und WriteFile vor CopyFile(Ex) vorzuziehen ist, um maximale Kompatibilität zu wahren?

Uwe Raabe 26. Dez 2017 18:23

AW: ReadFile und WriteFile durch Threads optmieren
 
Zitat:

Zitat von LTE5 (Beitrag 1389685)
Weil so kann ich
auf Abbrechen reagieren

Die entsprechende Windows-API wäre dann wohl CopyFileEx. Mit den geeigneten Parametern kannst du das jederzeit abbrechen und auch das Buffering abschalten.

Uwe Raabe 26. Dez 2017 18:26

AW: ReadFile und WriteFile durch Threads optmieren
 
Zitat:

Zitat von LTE5 (Beitrag 1389687)
Verstehe ich das richtig, dass, angenommen der Fall Program X wird von Windows XP bis 10 verwendet, ReadFile und WriteFile vor CopyFile(Ex) vorzuziehen ist, um maximale Kompatibilität zu wahren?

Gehört XP denn überhaupt zu den unterstützen Zielplattformen von Delphi 10.2 Tokyo? Ich glaube kaum: Unterstützte Zielplattformen

LTE5 26. Dez 2017 19:13

AW: ReadFile und WriteFile durch Threads optmieren
 
Mein Programm funktioniert noch wunderbar mit Windows XP.
Man muss nur aufpassen welche Winapi-Aufrufe man macht.

p80286 26. Dez 2017 19:23

AW: ReadFile und WriteFile durch Threads optmieren
 
Zitat:

Zitat von LTE5 (Beitrag 1389681)
Ist es möglich eine Kopierfunktion mit ReadFile und WriteFile so zu trennen, dass ReadFile und WriteFile je in einem Thread laufen?
ReadFile befüllt eine Art Liste von der ich noch absolut keine Ahnung habe wie das sein soll, aus der sich WriteFile dann bedient.

Oder ist ganz davon abzuraten?

Es kommt darauf an.
Falls Du die Aktion auf einem einzigen Datenträger ausführen willst könnte das kontraproduktiv sein, es kommt auf die Position(ierung) des Schreiblesekopfes/die Laufwerkselektronik an.
Gleiches gilt im übertragenen Sinne für SSD/USB-Sticks wobei die natürlich keinen Schreib-LeseKopf haben. Im günstigsten Falle, kannst Du den Vorgang um eine Buffergröße verschränken, so daß das Schreiben kurz nach dem Lesen erledigt ist. Ist das Zielmedium beim Schreiben schneller als das Quellmedium beim Lesen, mußt Du für das Schreiben auf jeden Fall ein paar Ehrenrunden mit einrechnen.

Wenn du keine Spezialanwendung hast, bei der Du richtig hardwarenah arbeiten mußt/kannst, halte ich die Idee für verschwendete Zeit. Die paar Zehntel, die Du heraus quetschen kannst, erfordern einen solchen Aufwand daß das nur als Hobby-Anwendung vertretbar ist.
Unterschätze den Test-Aufwand nicht!

Gruß
K-H

himitsu 1. Jan 2018 14:04

AW: ReadFile und WriteFile durch Threads optmieren
 
Klar kann man das durch Threads optimieren, aber wenn es sich um HDDs handelt, dann blockieren sie sich gegenseitig.
Also Threads machen da genau das Gegenteil und es wird langsamer.

Auch bei SSDs muß es nicht unbedingt besser werden. Kommt drauf an, ob die Firmware auch multithread arbeitet, aber meistens geht das.

Aber DU mußt nicht unbeding tselbst die Threads verwalten, denn WriteFile kann auch Asynchron arbeiten, also die API startet nur die Schreib-/Leseaktion und kehrt sofort zurück.
Du kannst dann parallel Mehrwas im selben Thread machen. > Overlapped IO

Optimieren kann man zusätzlich noch durch Wahl der Puffergröße im Programm, um die Anzahl der IO-Operationen zu optimieren/verringern.
Dann kann man noch vorallem den WindowsFileCache abschalten, da der bei so großen Datenmengen alles Andere auslagert. Selbst wenn Windows so eingestellt wurde, dass Programmespeicher Vorrang vor Cache hat, werden Programme ausgelagert und dann wird das System langsam.

https://msdn.microsoft.com/en-us/lib...(v=vs.85).aspx
> File Buffering, File Caching und Asynchronus I/O

Zitat:

Unstoppable Copier
Ich hatte noch nie so ein Schlechtes Programm gesehn.
Speziell wenn Fehler existieren, dann wird der Schott extrem langsam, da immer genau 1 Byte kopiert wird, aber wenn etwas kaputt ist, dann sind das immer koplette Sektoren, womit dann mehrmals Leseaktionen auf diese Sektoren ausgeführt werden und für jedes einzelne Byte dann erneut Timeouts/Fehlerpprüfung/Fehlerbehebung/... ausgelöst werden, anstatt nur einmal pro Sektor. :wall:
Und wenn ein Sektor kaputt ist, dann betrifft das im FileSystemTreiber einen Kompletten Cluster, was die Lesedauer nochmals verlierfacht.

Tipp: Meinen Hier im Forum suchenFileSplitter und seinen Post in der DP suchen ... da hatte ich damals mal so ordentlich mit den Lese-&Schreibzugriffen experimentiert.

LTE5 1. Jan 2018 16:28

AW: ReadFile und WriteFile durch Threads optmieren
 
Zitat:

Zitat von himitsu (Beitrag 1390015)
Zitat:

Unstoppable Copier
Ich hatte noch nie so ein Schlechtes Programm gesehn.

Ist der wirklich so schlecht? Ich benutze den recht häufig. Gibt es gute, portable Alternativen, die meine Daten nicht zerstören?

himitsu 1. Jan 2018 19:54

AW: ReadFile und WriteFile durch Threads optmieren
 
Er funktioniert, aber es war schwachsinnig zu denken, dass es so funktionieren könnte.
Das Teil liest in größeren Blöcken und bei einem Fehler wird der Block nochmal Byteweise gelesen, um die lesbaren Teile dieses Blocks zu bekommen.
Aber es ist können immer nur komplette Sektoren gelesen werden, also bringt es nichts, dieses Byte für Byte auszulesen.

Und das Teil nutzt die FileCache zum Auslesen, was hier nichts bringt.
Hätte Jason Hatley sich eine Minute mit NonBuffered I/O-Operationen beschäftigt, dann wäre es ihm aufgefallen.
OK, wenn man keine Ahnung hat, dann könnte man vielleicht auf die Idee kommen, dass es eine gute Möglichkeit wäre, mit dem byteweisen Zugriff. :stupid:

Ich hatte mal 'ne Festplatte, die "einige" defekte Sektoren besaß und brauchte über zwei Tage zum Kopieren der Platte.
> Reparaturversuche/Datenrettung nur auf einer zweiten Platte, falls dabei mehr kaput geht und man immernoch das Original hat.

Hatte dann später selbst eine billige Kopierfunktion geschrieben, und die war nach wenigen Stunden fertig.


Alle Zeitangaben in WEZ +1. Es ist jetzt 02:40 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz