Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Mit mehreren Threads auf einem physical Device schreiben (https://www.delphipraxis.net/128984-mit-mehreren-threads-auf-einem-physical-device-schreiben.html)

Zacherl 10. Feb 2009 17:27


Mit mehreren Threads auf einem physical Device schreiben
 
Hey,

ich wollte in einer meiner Anwendungen Mehrkern CPUs unterstützen und dachte mir, ich schreibe direkt mit mehreren Threads Daten auf eine Festplatte. In den verschiedenen Threads öffne ich das Device folgendermaßen:

Delphi-Quellcode:
hCurDevice := CreateFile(lpParam, GENERIC_ALL, FILE_SHARE_READ or
      FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0);
Nach dem ersten Mal bekomme ich mittels GetLastError allerdings die Meldung, dass die Datei nich geöffnet werden konnte, da sie von einem anderen Programm verwendet wird.

1. Frage: Lohnt es sich überhaupt mehrere Threads zu verwenden oder reicht ein Thread aus, da die Geschwindigkeit sowieso nicht vom CPU Speed, sondern viel mehr von der Schreibgeschwindigkeit der Festplatte abhämgt?
2. Frage: Wie kann ich das geschilderte Problem, fals es sich von der Performance her lohnt, lösen?

Gruß Zacherl

Apollonius 10. Feb 2009 17:39

Re: Mit mehreren Threads auf einem physical Device schreiben
 
Verändere mal die Zugriffsrechte auf GENERIC_READ or GENERIC_WRITE.

Um maximalen Durchsatz zu erreichen, würde ich nicht mehrere Threads nehmen, sondern mit Overlapped I/O arbeiten.

himitsu 10. Feb 2009 17:59

Re: Mit mehreren Threads auf einem physical Device schreiben
 
bei asynchronen Overlapped-I/Os könnte man auch nur ein Device-Handle nutzen :stupid:

bezüglich mehrfach gleichzeitig schreiben:
was ist denn das für ein Device?

Cyf 10. Feb 2009 18:09

Re: Mit mehreren Threads auf einem physical Device schreiben
 
Zitat:

Zitat von himitsu
was ist denn das für ein Device?

Zitat:

Zitat von Zacherl
ich schreibe direkt mit mehreren Threads Daten auf eine Festplatte.


Threads werden sich allerdings hier, wie schon genannt, nicht lohnen, da Festplattenzugriffe so ziemlich der größte Flaschenhals sind, den es gibt. :wink:
Overlapped I/O ist die bessere Lösung.

himitsu 10. Feb 2009 18:17

Re: Mit mehreren Threads auf einem physical Device schreiben
 
mist, die Festplatte hatte ich irgendwie übersehn :lol:

merkt man ja schon, wenn mehrere Programme auf der Festplatte rumkramen :?

Bei digitalen Speichermedien hätte es eventuell nicht so große Störungen ergeben können.

Drum hatte ich z.B. bei meinem FileSplitter extra kein paralleles Lesen/Schreiben implementiert und selbst die Schreib-/Lesezyklen wurden entsprechend angepaßt.

Zacherl 10. Feb 2009 18:35

Re: Mit mehreren Threads auf einem physical Device schreiben
 
Es geht um eine Test Anwendung für eine Informatik Arbeit, die die physische Platte nach folgendem Muster löscht:

Vom Begin an werden im Abstand von MAXINT 1Kb Zufallsdaten geschrieben. Ist das Ende der Platte erreicht, wird der Abstand halbiert und der Spaß geht von vorne los.

Selbstverständlich lohnt sich diese Methode nicht zum sicheren Datenlöschen, allerdings ist hier der Ansatz, möglichst viele Daten unbrachbar zu machen, um den Aufwand einer möglichen Wiederherstellung zu erschweren. Das ganze allerdings auch nur als Ergänzung einer "normalen" Formatierung ohne spezielle Methoden wie Gutmann, etc.

Ist overlapped IO mit diesem Zugriffsmuster hier möglich? Wenn ja, kann mir jemand ein Beispiel zur Verwendung geben?

Gruß Zacherl

alzaimar 10. Feb 2009 18:51

Re: Mit mehreren Threads auf einem physical Device schreiben
 
Das Märchen vom sicheren Löschen durch mehrmaliges Überschreiben wurde unlängst mal wieder als Mumpitz entlarvt. Bei Bedarf mal bei heise-online suchen (Oder hier klicken).

Auf die Spitze getrieben hat es ein Scherzkeks, der meinte, das das Überschreiben mit Nullen ja statischisch nur 50% der Bits löscht, die anderen waren ja vorher schon 0 :stupid:. Ergo wäre das einzig sichere Unkenntlichmachen von Daten das invertieren aller Bits, weil nur so garaniert 100% aller Bits betroffen sind.

Es reicht, die Daten einmal zu überschreiben. Ob nun mit Nullen, Einsen, Bitmustern oder dem Ave Maria ist Schnurzpiepegal. Herrlich, wie sich einige Hoax hartnäckig halten.

.... Hups: Ich sehe gerade, ihr macht es besser: Einfach mit Schrot (1kb Blöcke) auf die Festplatte schießen... Nette Idee.

Und: Ja, mit Overlapped I/O (WriteFileScatter) geht es schneller, allerdings nicht in 1K-Blöcken, sondern mit 8K (Größe einer Systempage).

himitsu 10. Feb 2009 18:58

Re: Mit mehreren Threads auf einem physical Device schreiben
 
du kannst/mußt bei Overlappt-IO bei jedem Schreib-/Lesezugriff die Position direkt angeben ... also der "bekannte" Filepointer wird von diesen Funktionen ignoriert.

mit ein KB-Daten würd ich da garnicht erst anfangen, da dafür die Zeit für's Positionieren des Schreiblesekopfes oft mehr Zeit benötigt, als das Schreiben selber.

Wenn du möglichst schnell viele Daten schrotten willst, dann ist 1 KB eh etwas suboptimal.

besorg dir die Clustergröße und die Position des esten Clusers.
renne dann über die Platte und vernichte erstmal die Zuordnungstabellen (bei FAT die erste FAT-Tabelle und bei NTFS die $MFTBitmap), dann vielleicht noch schnell die Dateisysteme schrotten und danach in Schritten von sagen wir mal mehreren Clustern jeweils ganze Cluster (oder mindestens die ersten 8 Sektoren) überschreiben ... nja und dann in halbschritten jeweils den Rest.

zu Overlappt > siehe mein Hier im Forum suchenFileSplitter und *überleg* hatte ich beim hSync den Code samt Overlappt und dem Anderem oben? :gruebel:

WriteFileScatter bringt in diesem Fall nichts, da es für eine andere Angelegenheit (z.B. Ringpuffer im PAM) ausgelegt ist.
und schneller als WriteFile ist es auch nicht (gibt's irgendwo hier 'nen kleinen Test von mir)

Zacherl 10. Feb 2009 20:15

Re: Mit mehreren Threads auf einem physical Device schreiben
 
Das klingt interessant :) Bin nicht so mit dem Aufbau der Platten und dem Dateisystem vertraut, aber die Größe der gesammten Platte ermittele ich mit:

Delphi-Quellcode:
type
  _DISK_GEOMETRY = record
    Cylinders: LARGE_INTEGER;
    MediaType: MEDIA_TYPE;
    TracksPerCylinder: DWORD;
    SectorsPerTrack: DWORD;
    BytesPerSector: DWORD;
  end;

DeviceIOControl und IOCTL_DISK_GET_DRIVE_GEOMETRY
Welchen Parameter von DeviceIOControl muss ich statt der GEOMETRY verwenden, um die Informationen zu erhalten? Ich bräuchte ja:
* Position des ersten Cluster
* Clustergröße
* Dateisystem (das wäre bei direkten Zugriff auf die physische Platte denke ich etwas kompliziert, da ja mehrere Partitionen drauf sein können)
* Position der Zuordnungstabellen (genau wie beim Dateisystem ja an die Partitionen gebunden)

Das komplette Überschreiben des ersten Clusters ist eine gute Idee. Hatte bisher einfach die ersten 20MiB genommen, um den MBR und die MFT zu überschreiben. Denke aber ab dem ersten Cluster arbeite ich dann lieber mit kleineren Paketen, da die Clustergröße im Normalfall ja schon recht groß ist.

Zitat:

Zitat von himitsu
WriteFileScatter bringt in diesem Fall nichts

In deinem FileSplitter findet sich leider nur ein Beispiel mit
Delphi-Quellcode:
Function WriteFileGather(hFile: THandle; aSegmentArray: pFILE_SEGMENT_ELEMENT;
  nNumberOfBytesToWrite: LongWord; lpReserved: PLongWord; lpOverlapped: POVERLAPPED): LongBool;
  StdCall; External 'kernel32.dll' Name 'WriteFileGather';
Aber in meinem Programm sollte ich stattdessen einfach weiterhin WriteFile() verwenden oder? Der Overlapped Zugriff sollte gleich sein.

Gruß Zacherl

Zacherl 11. Feb 2009 16:40

Re: Mit mehreren Threads auf einem physical Device schreiben
 
So hab nochmal nach anderen Control Codes für DeviceIOControl gesucht, aber dort scheint nichts passendes dabei zu sein.


Alle Zeitangaben in WEZ +1. Es ist jetzt 00:00 Uhr.
Seite 1 von 2  1 2      

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