AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

ReadFileScatter/WriteFileGatter

Ein Thema von himitsu · begonnen am 20. Dez 2006 · letzter Beitrag vom 10. Jan 2007
Antwort Antwort
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.049 Beiträge
 
Delphi 12 Athens
 
#1

ReadFileScatter/WriteFileGatter

  Alt 20. Dez 2006, 14:47
Moin,

ist zufällig in Sachen ReadFileScatter jemand weitergekommen?


Denn nach meinem Testprogramm bringt dieses anscheinend "nur" Nachteile.


Es ist ja schließlich nicht schneller als ein "normales" asynchrones und noncached ReadFile,
nur daß man erst den Speicher "mühevoll" in kleine Häppchen (je 1x SystemPageSize) zerlegen muß.

Und wenn genügend Teile bereits in der WindowsFileCache liegen, dann sind die "langsamen", darüber laufenden Funktionen schneller.
z.B. die über 700 MB/s, bei zwei 128 MB-Dateien sind ja wohl nicht zu verachten...


Im Anhang natürlich mein Testprojektchen,
zusammen mit den anderen Lese-Methoden.


PS:
laut meinem PSDK (WinXP SP2) soll FILE_SEGMENT_ELEMENT angeblich so aussehen:
Code:
typedef union _FILE_SEGMENT_ELEMENT {
    PVOID64 Buffer;
    ULONGLONG Alignment;
} FILE_SEGMENT_ELEMENT;
Delphi-Quellcode:
Type FILE_SEGMENT_ELEMENT = packed Record
    Buffer: Pointer64;
    Alignment: UInt64;
  End;
wie man sieht is alles 64 Bit groß, weßhalb ich es so definiert hatte:
Delphi-Quellcode:
Type FILE_SEGMENT_ELEMENT = packed Record
    Buffer, _fill: Pointer;
    Alignment: UInt64;
  End;
allerdings funktioniert es nur, wenn 32 Bit verwendet wird:
(wenn mehr als eine SystemPageSize gelesen werden soll)
Delphi-Quellcode:
Type FILE_SEGMENT_ELEMENT = packed Record
    Buffer: Pointer;
    Alignment: LongWord;
  End;

PSS:
Wenn zufällig noch jemand weiß wofür Alignment da sein soll?
Es hatte bei mir jedenfalls keine Auswirkungen und wenn MS was im Record freilassen wollte, dann heißt es ja sonst reserved, oder so.
Im PSDK steht zumindestens nichts drin.



[Anhang]
ClearCache: da ich ja keinen "direkten" einfluß auf die WindowsateiVerwaltung hab, kann/wird dieses vermutlich nicht bei jedem funktionieren ... als Ausweg könnte man auch den Rechner in den Ruhezustand (Hibernate) versetzen, denn da wird ebenfalls de FileCache geleert.

Im Bild sieht man verschiedene Testläufe, unter verschiedenen Bedingungen...
> mit FileCache
> mit FileCache - Dateien bereits geladen
> ohne FileCache

> auf dem selben Datenträger
> auf physich getrennten Datenträgern

Dann wurden noch die im Durchschitt besten Lese-Methoden angepunktet (markiert).


PS: wenn versucht wird gleichzeitig auf dem selben Laufwerk Dateien zu lesen/schreiben, dann wird natülich durch das ständige hin- und herspringen (zwischen den Dateien) alles ausgebremst.


[add]
Ich vergaß noch zu sagen, daß in den Sourcen keine Resourcenschutzblöcke und Fehlerabfragen vorhanden sind.
Für die kleine Demo werden diese nicht benötigt und würden wohl eher die Übersichtlichkeit über das Wichtigste behindern.
Wer also was daraus verwenden will, sollte sich dann die entsprechenden Dinge noch unbedingt einbauen!
Miniaturansicht angehängter Grafiken
readfilescatter_111.jpg  
Angehängte Dateien
Dateityp: zip readfilescatter_994.zip (155,6 KB, 17x aufgerufen)
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.049 Beiträge
 
Delphi 12 Athens
 
#2

Re: ReadFileScatter/WriteFileGatter

  Alt 3. Jan 2007, 19:20
Morschn,

beim weiteren Rumspielen mit ReadFileScatter/WriteFileGather ist unter Anderem auch noch dieses Programm rausgekommen.
Hier gibt es auch mal was zum Schreiben (WriteFileGather) ^^


Es ist sozusagen ein FileSplitter ... nocheiner

allerdings mal als sowas wie 'ne Konsolen-Anwendung mit MiniGUI.


'n Einblick in die möglichen Parameter:
Code:
FileSplitter -?                  // Hilfe
FileSplitter -s "abc.def" mb100  // Datei in 100MB-Stückchen zerlegen
FileSplitter -c "abc.def.part1" // Dateien wieder zusammensetzen
FileSplitter                    // GUI
Ohne Parameter und bei Falscheingaben kommen 2 bis 3 kleine Dialoge zur Parametereingabe.

In den Dialogen und per -? bekommt man natürlich Infos zu den einzelnen Parametern.


Und ja ich weiß ... für die Programmgröße wäre eine Abschaffung der Units SysUtils und Dialogs nicht schlecht.
Mal sehn, ob ich micn mal dazu durchringen kann diese abzuschaffen ... falls es jemand für nötig hällt. ._.

Eine Prozesanzeige fehlt und auf Resourcenschutzblöcke, sowie eine ordnungsgemäße Freigabe bei "Fehlern" wurde bewußt verzichtet,
da sich WinNT+ (NT4 2K XP Vista) ja auch schon so hervorragend um alle nötigen Dinge kümmert.



So, aber nun nochmal zu ein paar Besonderheiten und anderer Infos:
  • Zieldateiname wird aus der Quelldatei erzeugt
  • Zielverzeichnis entspricht dem Quellverzeichnis
  • SplitSize wird auf ein vielfaches der Sektor-Größe aufgerundet (meißt 512 Byte-Schritte)
    der Code würde sonst, auf Grund des NonCached-Read/Write, wesendlich aufwendiger werden müssen
  • Datum (LastWrite) und Attribute werden jeweils von der/den Ausgangsdatei(en) übernommen
    diese Daten gehen also nicht verloren
  • keine Fortschritsanzeige
    Ob das Programm noch läuft sieht man (nur) an den sich veränderten Dateien und im TaskManager,
    aber das Programmende wird entweder durch die Statistik, oder eine Exception angezeigt.
  • Registryeinträge, INIs, oder Ähnliches gibt es nicht
  • es wird mindestens Windows NT 4.0 SP2 benötigt
    siehe Requirements unter MSDN-Library durchsuchenReadFileScatter
zum QuellCode:
  • Kommentare gibt's kaum
  • 's ist vermutlich dennoch übersichtlich,
    vorallem da auf alles Überflüßig und Unnötige verzichtet wurde
    ansonsten ist der relevante Code recht kurz - abgesehn von den Prüfungen der Eingabeparameter...
  • ReadFileScatter und WriteFileGather zählen angeblich mit zu den schnellsten Dateiopperationen,
    wenn das stimmt, dann sollte dies der wohl schnellste FileSplitter sein
  • als Schreib-/Lesepuffer wurden mehrere aufeinanderfolgende Speicherblöcke verwendet, welche als Ganzes reserviert und dann Stückchenweise zugeordnet wurden
  • Resourcenschutzblöcke und Dergleichen fehlen,
    sind aber für diese Art von Programm nicht nötig (Windows kümmert sich darum)
    dennoch solltet ihr in euren Programmen soetwas vorsehen, jedenfalls wenn ihr nicht wißt wie sich Windows verhält


Falls noch Fragen offen sind oder Fehler auftreten, dann meldet euch einfach.
Ansonsten scheint das Programm bis jetzt fehlerfrei zu funktionieren.



PS: das Programm ist, auch wenn ich vermutlich irgendwann daran noch etwas weiterentwickle,
nicht wirklich für einen "Großeinsatz" gedacht ... vielmehr soll/kann es als Demo für die Verwendung von MSDN-Library durchsuchenReadFileScatter und MSDN-Library durchsuchenWriteFileGather diehnen.
Darum wird es vermutlich auch niemals mit so'ner schönen GUI wie bei den anderen FileSplittern ausgestattet
Angehängte Dateien
Dateityp: exe filesplitter_552.exe (158,0 KB, 4x aufgerufen)
Dateityp: dpr filesplitter_873.dpr (13,1 KB, 6x aufgerufen)
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#3

Re: ReadFileScatter/WriteFileGatter

  Alt 3. Jan 2007, 19:42
Mach mal bitte Geschwindigkeitstet mit meinem FileSplitter.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Olli
(Gast)

n/a Beiträge
 
#4

Re: ReadFileScatter/WriteFileGatter

  Alt 7. Jan 2007, 07:42
Ich glaube hier liegt ein Mißverständnis über den Sinn der Funktionen vor. Sie können bspw. ja zum Datentransfer von und zu Geräten (logisch "Dateien") benutzt werden. Und da hängt es ganz vom Treiber ab, ob und wie er das implementiert und ob es dadurch schneller wird.

Auch kann es sein, daß jemand schon sowas wie einen Ringpuffer oder ähnliches hat. Dann würde ihm die Funktion u.U. entgegenkommen. Man benutzt eben immer die Werkzeuge, die einem am besten "zur Hand gehen".

Zitat von himitsu:
Code:
typedef union _FILE_SEGMENT_ELEMENT {
    PVOID64 Buffer;
    ULONGLONG Alignment;
} FILE_SEGMENT_ELEMENT;
Delphi-Quellcode:
Type FILE_SEGMENT_ELEMENT = packed Record
    Buffer: Pointer64;
    Alignment: UInt64;
  End;
wie man sieht is alles 64 Bit groß, weßhalb ich es so definiert hatte:
Delphi-Quellcode:
Type FILE_SEGMENT_ELEMENT = packed Record
    Buffer, _fill: Pointer;
    Alignment: UInt64;
  End;
Du bist lustig ... das heißt, du übergibst mal eben eine 128bit-Struktur, wo nur eine 64bit-große stehen sollte?

Zitat von himitsu:
Wenn zufällig noch jemand weiß wofür Alignment da sein soll?
Es hatte bei mir jedenfalls keine Auswirkungen und wenn MS was im Record freilassen wollte, dann heißt es ja sonst reserved, oder so.
Im PSDK steht zumindestens nichts drin.
Da es sich um eine UNION handelt, wird dieser Wert natürlich dem "Pointer" entsprechen, weshalb man durch ein einfaches logisches AND das Alignment bestimmen kann ...

Und jetzt husch husch nochmal schnell das Thema Unions in meinem DLL-Tut nacharbeiten ...:

Delphi-Quellcode:
type
FILE_SEGMENT_ELEMENT = packed record
  case Integer of
    0: (Buffer: PVOID64);
    1: (Alignment: ULONGLONG);
end;
... bei der letzten Klammer bin ich nicht sicher, ob die vor oder nach dem Semikolon stehen muß, da ich zu faul bin BDS jetzt zu starten ... achja, und die Typen mußt du natürlich auf Delphi zurechtschneidern. Habe ich hier der Einfachheit halber nicht gemacht. Bsp. #2:

Delphi-Quellcode:
type
FILE_SEGMENT_ELEMENT = packed record
  case Integer of
    0: (Buffer, _fill: Pointer);
    1: (Alignment: UInt64);
end;
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.049 Beiträge
 
Delphi 12 Athens
 
#5

Re: ReadFileScatter/WriteFileGatter

  Alt 10. Jan 2007, 18:49
Dat mit der union hatte ich bei der Übersetzung wohl dodal übersehn.
Also, Wenn man es so sieht, dann passen die Typengrößen natürlich ... hätte ja beinah schon die Vermutung bekommen, dat die es im 32-Bit-Windows anders definiert hatten.


Hab's entsprechend geändert


Hatte grad keine neue Version von deinem FileSplitter da ... aber daß das noch nicht optimierte langsamer ist, war ja wohl klar.

Code:
Testdatei: 2,4 GB
Meines:     9:39, 9:37
dein Altes: 16:18, 14:02  (5.5.5.1228 28.12.05)
ein aktuellerer Vergleich folgt vermutlich morgen.


Aber 'nen kleinen Test hatte ich dennoch mal gemacht ... ReadFileScatter ist wohl 'nen Hauch schneller gewesen
Code:
4.000.000.000 Byte

ReadFile+NoCache        89,828 s = 42,5 MB/s
ReadFile+NoCache+Async  67,797 s = 56,3 MB/s
ReadFileScatter         67,781 s = 56,3 MB/s
Ach ja, bei dem Testprogramm:
ersma "kleinen" Fehler behoben



dieses
Delphi-Quellcode:
FillMemory(@A1[0], SizeOf(A1), 0);
FillMemory(@A2[0], SizeOf(A2), 0);
durch Folgendes ersetzt
Delphi-Quellcode:
FillMemory(@A1[0], Length(A1) * SizeOf(FILE_SEGMENT_ELEMENT), 0);
FillMemory(@A2[0], Length(A2) * SizeOf(FILE_SEGMENT_ELEMENT), 0);
ReOpenFile-Ersatz eingefügt - wegen SetFilePointer + not sector-aligned + FILE_FLAG_NO_BUFFERING
siehe MSDN-Library durchsuchenSetFilePointer


Und dann noch einiges anderes nachgerüstet ... jetzt sollten wohl schonmal “alle“ möglichen Lese-/Schreibmethoden vorhanden sein.
Muß aber noch ein bissl was ändern ... ist halt nicht so ganz leicht ein halbwegs “gerechtes“ Prüfszenario für alle Metoden zusammenzustellen, vorallem wenn die etwas “chaotische und nicht zu steuernde“ SystemCache so mitspielen soll, wie sie es soll

[add]
ach ja, dat SetFilePointer+NotSectorAligned+FILE_FLAG_NO_BUFFE RING-Problem betraf natürlich auch dieses Programm, daher hier auch nochmal 'ne aktuelle Version ... 's wäre ja nicht schön wenn plötzlich ein paar Bytes mehr in der geteilten Datei auftauchen
Angehängte Dateien
Dateityp: zip readfilescatter_164.zip (225,5 KB, 13x aufgerufen)
Dateityp: exe filesplitter_483.exe (158,0 KB, 8x aufgerufen)
Dateityp: dpr filesplitter_102.dpr (13,6 KB, 10x aufgerufen)
Neuste Erkenntnis:
Seit Pos einen dritten Parameter hat,
wird PoSex im Delphi viel seltener praktiziert.
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:32 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