2008-09-29 1 views
37

Ich genieße es, Algorithmen mit der STL zu entwickeln, jedoch habe ich dieses wiederkehrende Problem, wo meine Datensätze für den Haufen zu groß sind.Festplattengestützte STL-Containerklassen?

Ich habe nach drop-in Ersetzungen für STL-Container und Algorithmen gesucht, die disk-backed sind, d. H. Die Datenstrukturen werden auf der Festplatte und nicht auf dem Heap gespeichert.

Ein Freund wies mich vor kurzem auf stxxl. Bevor ich mich zu sehr damit beschäftige ... Gibt es andere disk-gestützte STL-Ersetzungen, die ich in Betracht ziehen sollte?

HINWEIS: Ich bin nicht in Persistenz oder eingebetteten Datenbanken interessiert. Bitte erwähnen Sie nicht Boost :: Serialisierung, POST ++, relationale Template-Bibliothek, Berkeley DB, SQLite usw. Ich kenne diese Projekte und verwende sie, wenn sie für meine Zwecke geeignet sind.

UPDATE: Mehrere Personen Speicher-Mapping-Dateien und die Verwendung eines benutzerdefinierten allocator erwähnt haben, gute Vorschläge BTW, aber ich würde sie auf die Diskussion here zeigen, wo David Abraham schlägt vor, dass individuelle Iteratoren würde für Disk-backed-Container benötigt werden . Das bedeutet, dass der benutzerdefinierte Allokator-Ansatz wahrscheinlich nicht funktioniert.

+0

Wenn Ihre Datasets für den Heap zu groß sind, sollten Sie überlegen, ob Ihre Systemarchitektur korrekt ist (z. B. ob zu einem 64-Bit-System gewechselt wird; diese sind jetzt häufiger als bei der Abfrage). Sie sollten auch überlegen, ob die STL der richtige Ansatz ist; Es kann Annahmen über die Datenmenge geben, die für Sie nicht gelten. –

+0

@Donal Er reserviert möglicherweise nicht die richtige Menge an Speicher. –

Antwort

10

Ich habe etwas sehr ähnliches implementiert. Die Implementierung der Iteratoren ist die größte Herausforderung. Ich habe boost::iterator_facade verwendet, um die Iteratoren zu implementieren. Mit können Sie einfach anpassen alle im Cache Disk Datenstrukturen, um eine STL-Container-Schnittstelle zu haben.

+0

Ich benutze Boost, aber iterator_facade ist neu für mich. Ich muss mir das mal anschauen, danke fürs Teilen. – paxos1977

+0

Möchten Sie die Implementierung freigeben? –

+0

Leider kann ich diesen Code nicht teilen. Aber wenn Sie irgendwelche Fragen haben, würde ich mehr als glücklich sein zu helfen. – Ted

2

Ich weiß nicht viel über das Thema, aber es könnte möglich sein, eine STL-ähnliche Schnittstelle in eine Memory-Mapped-Datei zu schreiben?

bearbeiten: Dieser Ansatz eignet sich möglicherweise, wenn Sie versuchen, einen bestimmten Teil einer großen Datei zu erhalten. Wenn Sie versuchen, etwas mit der gesamten Datei zu tun, werden Sie wahrscheinlich eine große Anzahl von Seitenfehlern erzeugen, wenn Sie nicht zwischengespeicherte Teile der Datei lesen.

+0

Ich habe überlegt, dies zu tun ... aber ich würde es lieber nicht selbst schreiben, wenn schon etwas brauchbares getan wurde. – paxos1977

+0

Ich kann es schätzen, das Rad nicht neu erfinden zu wollen. Ich kenne keine Bibliothek, die das tut; Hoffentlich kann jemand einen empfehlen. – luke

+0

Ich glaube, Boost.Interprocess kann verwendet werden, um in eine Memory-Mapped-Datei zu schreiben. Habe es aber nicht probiert. –

3

Wenn Sie (wie Sie schreiben) nicht an Persistenz interessiert sind, besteht die einfachste Lösung darin, die Größe des Heapspeichers zu erhöhen und die virtuellen Speicher des Betriebssystems zu verwenden. Der Teil des Heapspeichers, der nicht in den physischen Arbeitsspeicher Ihres Computers passt, wird am Ende auf den Datenträger ausgelagert und bietet Ihnen genau das, was Sie wollen: normaler STL-Zugriff auf häufig auf Festplatte gespeicherte Daten. Das Betriebssystem sorgt dafür, dass die am häufigsten verwendeten Seiten im physischen Speicher zwischengespeichert und auf die Festplatte ausgelagert werden, die Sie nicht häufig verwenden. Ihr Code bleibt gleich, und Sie können seine Leistung erhöhen, indem Sie einfach mehr physischen Speicher hinzufügen.

Um Ihre Heap-Größe zu erhöhen, überprüfen Sie die Parameter Ihres Betriebssystems, wie ulimit (1) auf Unix-Systemen und Systemeigenschaften - Erweitert - Leistung - Erweitert - Virtueller Speicher unter Windows XP. Wenn Sie die 32-Bit-Grenze von 4 GB erreicht haben, ziehen Sie in Betracht, in eine 64-Bit-Architektur zu wechseln oder Ihr Programm für 64 Bit zu kompilieren.

+0

Ich bin ein kompetenter Systemadministrator, ich habe den von Ihnen vorgeschlagenen Ansatz berücksichtigt. Ich habe eine AMD64-Maschine, die unix läuft. Ich kann es mir nicht leisten, mehr physischen Speicher hinzuzufügen. Mein Swap-Speicherplatz ist 2 GB, mein Datensatz ist 42 GB, meine Festplatte ist 1 TB ... – paxos1977

+1

Also, wie wäre es, Ihren Swap-Speicherplatz zu erhöhen? – Arkadiy

+0

Sicher, ich habe über den Wiederaufbau meines Servers nachgedacht, um dieses Projekt unterzubringen. Dies ist jedoch keine dedizierte Hardware, sondern eine Maschine für allgemeine Forschung. Darüber hinaus müssen die Mitarbeiter schließlich auch den Code ausführen, und ich denke nicht, dass sie ihre Maschinen neu erstellen müssen. – paxos1977

8

Ich habe noch nie so etwas tun müssen, aber es könnte möglich sein, was Sie tun möchten, indem Sie einen benutzerdefinierten Zuordner schreiben, der eine Speicherabbilddatei verwendet, um Ihre Daten zu sichern.

Siehe boost::interprocesses für Dokumente auf ihre einfache Implementierung von Speicherdateien abgebildet zu verwenden, this Dr. Dobbs article für eine detaillierte Diskussion über das Schreiben Verteilern und this IEEE Software column für eine Beschreibung des Problems und example code.

+0

Ich kenne den DDJ Artikel, schönen Artikel. Es gab jedoch eine Diskussion über die Mailing-Liste von Boost zwischen Terpstra, Kuehl & Abraham, was nahe legt, dass benutzerdefinierte Iteratoren benötigt werden, um mit Datenstrukturen auf der Festplatte umzugehen ... was den Custom-Allocator-Ansatz ausschließt. – paxos1977