Effiziente Möglichkeit, Daten auf der Festplatte zu speichern, während eine rechenintensive Aufgabe ausgeführt werden

StackOverflow https://stackoverflow.com/questions/1014113

Frage

Ich arbeite an einem Stück wissenschaftlicher Software, die sehr rechenintensiv (wenn sein Proc ausgelöst bound) ist, aber es muss Daten auf dem Datenträger schreiben ziemlich oft (i / o gebunden).

Ich füge Parallelisierung zu dieser (OpenMP) und ich frage mich, was der beste Weg, um den Write-to-Disk-Bedarf zu decken. Es gibt keinen Grund, die Simulation auf der Festplatte warten soll (das ist, was er tut jetzt).

Ich bin auf der Suche nach einem ‚best practice‘ für diese, und die Geschwindigkeit ist, was mir am meisten am Herzen (diese können enorm lange Simulationen sein).

Danke ~ Alex

Erste Gedanken:

einen separaten Prozess mit tun, um die eigentliche Schreiben auf die Festplatte, so dass die Simulation zwei Prozesse hat: eine CPU-bound (Simulation) und ist IO-gebunden (Datei zu schreiben). Das klingt kompliziert.

Vielleicht ein Rohr / Puffer? Ich bin ein bisschen neu zu diesen, so vielleicht, dass könnte eine mögliche Lösung sein.

War es hilfreich?

Lösung

Wenn Sie OpenMP zu Ihrem Programm Umsetzung dann ist es besser, zu verwenden #pragma omp Single oder #pragma omp Master aus parallelem Abschnitt in Datei zu speichern. Diese pragmas erlauben nur ein Thread etwas auszuführen. So können Sie Code aussehen wie folgt:

#pragma omp parallel
{
    // Calculating the first part
    Calculate();

    // Using barrier to wait all threads
    #pragma omp barrier

    #pragma omp master
    SaveFirstPartOfResults();

    // Calculate the second part
    Calculate2();

    #pragma omp barrier

    #pragma omp master
    SaveSecondPart();

    Calculate3();

    // ... and so on
}

Hier Team von Threads Berechnung tun, sondern nur einzelner Thread Ergebnisse auf der Festplatte speichern.

Es sieht aus wie Software-Pipeline. Ich schlage vor, Sie TBB :: Pipeline Muster von Intel Threading Building Blocks Bibliothek zu betrachten. Ich kann Ihnen das Tutorial auf Software-Pipelines unter http://cache-www.intel.com/cd/00/00/30/11/301132_301132.pdf#page=25 . Bitte lesen Sie Abschnitt 4.2. Sie lösten das Problem: einen Thread aus dem Laufwerk zu lesen, zweiter zu verarbeiten Strings lesen, dritter zu speichern zu fahren

.

Andere Tipps

Ich würde sagen, der beste Weg, einen anderen Thread erzeugen würde, die Daten zu speichern, nicht ein völlig neues Verfahren; mit einem neuen Verfahren, führen Sie sich die Mühe, um die Daten zu kommunizieren über die Prozessgrenze gespeichert werden, die eine neue Reihe von Schwierigkeiten führt.

Die erste Lösung, die den Sinn kommt, ist ziemlich viel, was Sie gesagt haben - Scheibe mit schreibt in ihrem eigenen Prozess mit einem One-Way-Rohr von der SIM an den Schriftsteller. Der Autor macht schreibt so schnell wie möglich (Zeichnung neue Daten aus dem Rohr). Das Problem dabei ist, dass, wenn die SIM zu weit vor dem Schriftsteller bekommt, wird die SIM geht an dem Rohr schreibt zu blockieren sowieso, und es wird I / O an einem Entfernen gebunden sein.

Das Problem ist, dass Ihr Simulationszyklus in der Tat nicht abgeschlossen ist, bis er die Ergebnisse Spits aus.

Das zweite, was mir einfällt, ist nicht blockierende E / A zu verwenden. Jedes Mal, wenn die SIM-Karte schreiben muss, sollte es tut dies über nicht blockierende E / A. Auf der nächste Notwendigkeit zu schreiben, kann es dann die Ergebnisse der vorherigen I / O-Operation abholen vor dem Start die neuen (möglicherweise eine kleine Wartezeit entstehen). Dies hält die Simulation so weit wie möglich parallel zu dem I / O läuft die Simulation bekommt sehr weit vor dem Schreiben ohne Stich gelassen.

Die erste Lösung wäre besser, wenn der Simulation Verarbeitungszyklus variiert (manchmal kleiner als die Zeit für einen Schreib, manchmal auch länger), da im Durchschnitt die Schreibvorgänge mit der SIM halten könnten.

Wenn der Verarbeitungszyklus ist immer (oder fast immer) geht, dass sie kürzer ist als die Schreibzeit  dann könnten Sie auch nicht mit dem Rohr stören und einfach zu verwenden, nicht blockierende I / O, denn wenn man das Rohr verwenden wird es schließlich füllen und die SIM wird auf das ich bekommt hängte / O sowieso.

Da Sie CPU und IO sind gebunden: Lassen Sie mich raten: Es gibt immer noch genügend Speicher vorhanden, rechts

Wenn dies der Fall sollten Sie die Datenpuffer, die erweitern auf die Festplatte in den Speicher zu einem bestimmten geschrieben werden muss. Schreiben große Teile von Daten ist in der Regel viel schneller als kleine Stücke zu schreiben.

Für das Schreiben selbst: Betrachten Speicher mit abgebildet IO. Es ist schon eine Weile her, seit ich gebenchmarkt habe, aber das letzte Mal habe ich es war signifikant schneller.

Sie können auch immer ein wenig CPU vs. IO handeln. Ich glaube, Sie zur Zeit die Daten als eine Art von rohen, unkomprimierten Daten zu schreiben, nicht wahr? Sie können einige IO Leistung, wenn Sie ein einfaches Komprimierungsschema verwenden die Datenmenge zu reduzieren, geschrieben werden. Die zlib-Bibliothek ist ziemlich einfach, mit zu arbeiten und komprimiert sehr schnell auf die niedrigste Komprimierungsstufe. Es hängt von der Art der Daten, aber wenn es eine Menge Redundanz darin sogar ein sehr grober Komprimierungsalgorithmus kann das IO gebunden Problem beseitigen.

Ein Thread führt kontinuierlich einen Schritt des rechenintensiver Prozess und fügt dann das Teilergebnis in eine Warteschlange von Teilergebnissen. Ein anderer Thread entfernt kontinuierlich Teilergebnisse aus der Warteschlange und schreibt sie auf der Festplatte. Achten Sie darauf, den Zugriff auf die Warteschlange zu synchronisieren. Eine Warteschlange ist eine Liste ähnliche Datenstruktur in dem Sie Elemente an das Ende und entfernen Sie Elemente aus der Front hinzufügen können.

Machen Sie Ihre Anwendung zwei hat Fäden , einen für CPU und einen für die Festplatte.

Hat die CPU Gewinde Push-Daten in eine Warteschlange abgeschlossen, die die Festplatten Faden zieht dann aus als Daten kommen in.

Auf diese Weise die CPU wird nur die Daten los und läßt jemand anderes damit umgehen und die Festplatte nur wartet geduldig auf irgendwelche Daten in der Warteschlange.

Die Umsetzung weise, könnten Sie die Warteschlange als Shared-Memory-Objekttyp tun, aber ich denke, ein Rohr würde genau das, was Sie würde suchen. Die CPU schreibt einfach an das Rohr, wenn nötig. Auf der Seite Festplatte, würden Sie gerade gelesen das Rohr und wann immer Sie gültige Daten bekamen, gehen von dort aus.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top