Ich habe eine kleine IO-Klasse implementiert, die von mehreren und gleichen Dateien auf verschiedenen Festplatten (z. B. zwei Festplatten, die die gleiche Datei enthalten) lesen kann. Im sequenziellen Fall lesen beide Platten durchschnittlich 60MB / s über die Datei, aber wenn ich einen Interleaved mache (z. B. 4k-Disk 1, 4k-Disk 2, dann kombinieren), wird die effektive Lesegeschwindigkeit auf 40MB / s reduziert, statt zu erhöhen?
Kontext: Win 7 + JDK 7b70, 2GB RAM, 2.2GB Testdatei. Grundsätzlich versuche ich Win7s ReadyBoost und RAID x in armer Manier zu imitieren.
Wenn im Kern eine read () -Ausgabe an die Klasse ausgegeben wird, erstellt sie zwei Runnables mit Anweisungen zum Lesen einer bereits geöffneten RandomAccessFile ab einer bestimmten Position und Länge. Mit einem Executor-Service und Future.get () -Aufrufen, wenn beide fertig sind, wird das gelesene Daten in einen gemeinsamen Puffer kopiert und an den Aufrufer zurückgegeben.
Gibt es einen konzeptionellen Fehler in meinem Ansatz? (Zum Beispiel wird der OS Caching-Mechanismus immer gegensteuern?)
%Vor%(FileMetrics im Metrik-Array enthält Messungen der Lesegeschwindigkeit, um die Puffergrößen verschiedener Eingangskanäle adaptiv zu bestimmen - in meinem Test mit alpha = 0 und readSpeed = 1 gleiche Verteilung)
Bearbeiten Ich führte einen nicht verwickelten Test durch (z. B. lies die zwei Dateien unabhängig voneinander in separaten Threads) und ich habe eine kombinierte effektive Geschwindigkeit von 110 MB / s.
Bearbeiten2 Ich denke, ich weiß, warum das passiert.
Wenn ich parallel und sequentiell lese, ist das kein sequentielles Lesen für die Platten, sondern ein Lesen-Überspringen-Lesen-Überspringen-Muster aufgrund der Verschachtelung (und möglicherweise durchsucht mit Zuweisungstabellennachschlagen). Dies reduziert grundsätzlich die effektive Lesegeschwindigkeit pro Platte auf die Hälfte oder weniger.
Wie Sie gesagt haben, ist ein sequentielles Lesen auf einer Platte viel schneller als ein Lesen-Überspringen-Lesen-Überspringen-Muster. Festplatten sind beim sequentiellen Lesen in der Lage, eine hohe Bandbreite zu haben, aber die Suchzeit (Latenz) ist teuer.
Anstatt eine Kopie der Datei auf jeder Festplatte zu speichern, versuchen Sie, den Block i der Datei auf der Festplatte i zu speichern (Mod 2). Auf diese Weise können Sie sequentiell von beiden Festplatten lesen und das Ergebnis im Speicher neu kombinieren.
Wenn Sie sicher sind, dass Sie nicht mehr als einen Lesevorgang pro Datenträger ausführen (sonst haben Sie viele Datenträgerfehler), erstellen Sie weiterhin Konflikte in anderen Teilen des Computers - dem Bus, dem RAID-Controller (falls vorhanden) und so weiter an.
Tags und Links java multithreading file-io