Wie Windows-Diskpuffer/Dateicache leeren ? [Erledigt]

Windowsspezifisches Forum , API ,..
Beiträge, die plattformübergreifend sind, gehören ins 'Allgemein'-Forum.
Benutzeravatar
TheCube
Beiträge: 169
Registriert: 20.07.2010 23:59
Computerausstattung: Risen 3400G 16MB Win10-64Bit
Wohnort: NRW

Wie Windows-Diskpuffer/Dateicache leeren ? [Erledigt]

Beitrag von TheCube »

Hallo! Mein Problemchen wurde vielleicht schonmal behandelt, und es scheitert
mal wieder nur am richtigen Suchbegriff /:-> .... aber man kanns bestimmt nur
per Windows-API lösen, deshalb hier.

Um zu Testzwecken "schön langsam" zu sein schliesse ich einen USB-Stick über
einen alten USB-Repeater an. (max 1MB/s schreiben/lesen) Darauf befindet sich ein Testfile von ca. 30MB.
Bei Schreiben zum Stick (z.B. per WriteData aus dem Speicher) stellt sich auch immer
die erwartete Geschwindigkeit von knapp 1 MB/s ein. Auch bei Wiederholungen.
(Bei meiner internen SATA-HD gibts aber auch hier schon Phantasiewerte bis 500MB/s, ist jetzt aber egal.)

Aaaber beim Lesen :

Code: Alles auswählen

*MemID = AllocateMemory(1048576*32)        ; 32MB reservieren
filenr= OpenFile(#PB_Any, "G:\Testfile")   ; Inklusive Pfad
;FlushFileBuffers(filenr)         ; Bringt nix (?)
;FileBuffersSize(filenr, 0)       ; Bringt nix (?)
Debug "Datei geöffnet"
length = Lof(filenr) : Debug length
    If filenr
      wb=ReadData(filenr, *MemID, length)   ; Datei in Speicherblock schreiben
    EndIf  
Debug "Datei gelesen"    
Debug PeekS(*MemID,200)    
CloseFile(filenr)
Debug CRC32FileFingerprint("G:\Testfile")
Zwischen ""Datei geöffnet" und "Datei gelesen" vergehen nur beim ersten Start die erwarteten ca. 30s.
Beim weiteren Starts liegen dazwischen nur Sekundenbruchteile. Genauso beim Lesen via CRC32FileFingerprint.
Ergo fliessen über die physikalisch langsame USB-Verbindung keine Daten. Aber eben das möchte ich erzwingen.
Auch ein Umbenennen des Testfile oder ändern von Bytes im Testfile per Hexeditor ändern da nichts,
wenngleich die Hexeditor-Änderungen danach korrekt eingelesen wurden. Win7-Vodoo :?

Kann man da was machen, ausser Gigabyte-grosse Files zu verwenden ?
Zuletzt geändert von TheCube am 05.03.2012 02:27, insgesamt 1-mal geändert.
Benutzeravatar
PMV
Beiträge: 2765
Registriert: 29.08.2004 13:59
Wohnort: Baden-Württemberg

Re: Wie Windows-Diskpuffer/Dateicache leeren ?

Beitrag von PMV »

FileBuffersSize(filenr, 0) deaktiviert den Cache für Dateien nach meinem
Verständnis nur fürs schreiben. Das lesen dürfte Windows dann mit dem RAM
beschleunigen oder/ und die HDD ihren Lesepuffer verwenden.
alte Projekte:
TSE, CWL, Chatsystem, GameMaker, AI-Game DLL, Fileparser, usw. -.-
Benutzeravatar
TheCube
Beiträge: 169
Registriert: 20.07.2010 23:59
Computerausstattung: Risen 3400G 16MB Win10-64Bit
Wohnort: NRW

Re: Wie Windows-Diskpuffer/Dateicache leeren ?

Beitrag von TheCube »

Das lesen dürfte Windows dann mit dem RAM beschleunigen
Ja, darum gehts ja ... Windows soll "vergessen" das Testfile schonmal angepackt zu haben und die Daten real über die Leitung holen.
... / und die HDD ihren Lesepuffer verwenden
Dem HDD-Cache kann man m.E. sowieso nicht ins Handwerk pfuschen, weshalb ich mich mit den unmöglich hohen Schreibraten da auch abfinde.
Ich teste aber mit einem Cache-losen USB-Stick.
Benutzeravatar
TheCube
Beiträge: 169
Registriert: 20.07.2010 23:59
Computerausstattung: Risen 3400G 16MB Win10-64Bit
Wohnort: NRW

Re: Wie Windows-Diskpuffer/Dateicache leeren ?

Beitrag von TheCube »

Iss ja´n Ding .... da muss ich mir im API-Experten-Unterforum meine eigene Frage lösen ..... :wink:
Um das gewissermaßen viel zu schnelle Lesen (weil aus Windows-Cache) zu unterbinden habe ich folgende Lösung:

Code: Alles auswählen

hFile = CreateFile_("X:\testfile",#GENERIC_READ, #FILE_SHARE_READ, #Null, #OPEN_EXISTING, #FILE_ATTRIBUTE_NORMAL | #FILE_FLAG_NO_BUFFERING, #Null)
If hFile <> #INVALID_HANDLE_VALUE : CloseHandle_(hFile) : Else : Debug "File nicht vorhanden!" : EndIf
Einfach kurz vor die Purebasic-Dateioperation (wie Open/Readfile oder z.B. CRC32FileFingerprint) setzen, wenn erforderlich.
Das flushed bei mir die Caches und alles dauert so lange wie es aufgrund der geringen Datenrate (s.o. 1 MB/s) auch dauern müsste.
Und klar, ich könnte das ReadData(filenr, *MemID, length) von PB dann natürlich direkt gegen ReadFile_(hFile, *MemID, BytestoRead, @BytesRead, #Null) aus der API ersetzen.
Das Schreiben von Testfiles nach der Methode komplett per API muss ich noch testen, wird auf int. HDD´s wahrscheinlich auch etwas "realistischer" im Datendurchsatz ausfallen.

Edit:
Ja, sogar hier (write) klappts jetzt ohne (für mich) störende Caches. Als Beispiel ein aus dem Zusammenhang gerissener Schnipsel:

Code: Alles auswählen

actBytes.l=0
hFile = CreateFile_(*FWparam1\Fname, #GENERIC_READ | #GENERIC_WRITE, #FILE_SHARE_READ, #Null, #OPEN_ALWAYS, #FILE_ATTRIBUTE_NORMAL | #FILE_FLAG_WRITE_THROUGH, #Null)
If hFile <> #INVALID_HANDLE_VALUE
  wb=WriteFile_(hFile, *MemID, Fsize, @actBytes.l, #Null) ; Speicherblock in die Datei schreiben
  CloseHandle_(hFile)                                     ; die zuvor geöffnete Datei schließen & speichern
EndIf
Antworten