2015-07-22 8 views
7

In meiner Software habe ich 4x 500GB Dateien, die ich schreibe sequenziell in einer kreisförmigen Art und Weise mit Speicher-Mapped File APIs.Disk IO Problem mit zirkulären Datei schreibt

Ich zuteile Regionen in 32MB Blöcken, und wenn ich am Ende einen Block zuweisst, erstelle ich zwei Speicherbereiche, wobei der erste das Ende der Datei ist und der zweite am Anfang der Datei und der Endadresse zugeordnet ist der ersten Region.

Jetzt funktioniert das gut mit kleineren Dateien. Wenn jedoch große Dateien in die Endregion gelangen, geht die Datenträgerleistung zu Boden und ich bin mir nicht sicher, wie ich sie vermeiden kann.

Ich vermute, dass die Platte versucht, an beide Enden der Dateien zu schreiben, und die Spindel muss vor und zurück springen. Das ist ziemlich albern, besonders beim sequentiellen Schreiben, und ich hätte gehofft, dass das Betriebssystem etwas schlauer wäre.

Hat jemand Ideen, wie Sie dieses Problem vermeiden können?

Ich dachte an ein Upgrade auf Windows 10 und hoffe, dass es einen besseren Job macht. Aber es ist eine ziemlich riskante Veränderung, die ich jetzt vermeiden möchte.

Ich sollte auch beachten, dass die Dateien auf einem Software-RAID 1 mit 2x 3TB Seagate Constalation Enterprise-Laufwerke lebt. Diese Laufwerke haben eine minimale Schreibgeschwindigkeit von 60MB/s und eine durchschnittliche Schreibgeschwindigkeit von 120MB/s. Insgesamt schreibe ich mit allen Dateien mit einer Geschwindigkeit von 30 MB/s.

Der Code kann here gefunden werden.

EDIT:

es so stellt sich heraus, nachdem sie auf die gesamte Datei zu schreiben und dann von dem das Betriebssystem starten Start über tatsächlich beginnt das Lesen zurück, was auch auf der Festplatte ist, obwohl es nicht notwendig ist, das, was ich glaube verursacht die Probleme.

+0

Wie messen Sie die Festplattenleistung und was ist die Grenze der Dateien, nach denen das Problem auftritt? –

+0

Ich teste gerade mit immer kleineren Dateien. Obwohl es ungefähr einen Tag dauert, bevor es das Ende erreicht. Ich werde aktualisieren, wie ich mehr Ergebnisse bekomme. – ronag

+0

Ich messe es durch den Schreibpuffer, ich habe 4x heißen Quellen, die Daten in 4 x 7,5 MB/s sendet und jedes Eingabepaket wird gepuffert. Wenn der Puffer anfängt zu wachsen, bedeutet dies, dass die Datei nicht schnell genug geschrieben wird und wenn sie 4 GB erreicht, fängt sie an, Pakete fallen zu lassen, was gerade geschieht, nachdem sie die fragliche Region erreicht hat. – ronag

Antwort

1

"Diese Laufwerke haben eine sequentielle Schreibgeschwindigkeit von mindestens 60 MB/s" - was irrelevant ist, weil Sie keine sequentiellen Schreibvorgänge ausführen.

Verwenden Sie SSD-Caching, oder überdenken Sie den Entwurf (finden Sie einen Weg, um den Zugriff über die Pufferumgehung zu verhindern).


Nicht zum spee bezogen werden: Sie könnten nur einen Ringpuffer direkt in die Datei abgebildet verwenden, so dass Sie nicht verwenden müssen (proprietär?) Tricks „aufeinanderfolgende“ Adressbereiche abzubilden. Die grobe Idee: boost::circular_buffer equivalent for files?

+0

Nun, die Art und Weise, wie ich in 32MB Blöcken schreibe, ist ziemlich genau so wie sequentiell, die Suchzeit auf den Laufwerken beträgt ~ 50ms, was bedeutet, dass es nicht einmal einen theoretischen Overhead von 0,01% gibt. – ronag

+0

Ich kann boost :: circular_buffer nicht aus verschiedenen Gründen verwenden, unter anderem, dass ich nicht die gesamte Datei in einem Rutsch abbilden kann. Ich habe das ausprobiert und der Rechner hat keinen Speicher mehr und stürzt ab. – ronag

+0

Warum nicht? Ist der Puffer nicht in der Größe festgelegt? Sind Sie in einem 16-Bit-Adressraum? – sehe