2010-11-12 15 views
11

Ich bin auf der Suche nach einer definitiven Antwort (wenn in der Tat eine existiert) auf wie viel Speicher sollte beim Erstellen eines statischen Chunks von Shared Memory über boost::interprocessmanaged_shared_memory zugeteilt werden. Selbst official examples scheinen arbitrarily large Chunks des Speichers zuzuordnen.Wie viel Speicher sollte "managed_shared_memory" zuweisen? (Boost)

Betrachten Sie die folgende Struktur:

// Example: simple struct with two 4-byte fields 
struct Point2D { 
    int x, y; 
}; 

Meine erste Reaktion ist, dass die notwendige Größe 8 Bytes sein würde, oder sizeof(Point2D). Dies schlägt kläglich fehl, wenn ich versuche, ein Objekt zu konstruieren, das mir Seg-Fehler zur Laufzeit gibt.

Welcher Lese-/Schreibvorgang verursacht Seg-Fehler? Stapeloperationen? Temporäre Zuteilungen innerhalb von segment.construct()? Wie viel Overhead ist erforderlich, wenn Shared Memory zugewiesen wird?

Durch Versuch und Irrtum fand ich, dass die Multiplikation der Größe mit 4 für die obige Struktur funktionieren kann, aber auseinander fällt, wenn ich anfange, weitere Felder zu meinem struct hinzuzufügen. Also, das riecht nach einem schlechten Hack.

Einige mögen argumentieren, dass "Speicher ist billig" in der modernen PC, aber ich stimme nicht mit dieser Philosophie und Abneigung, mehr als ich brauche zuweisen, wenn ich es vermeiden kann. Ich habe gestern die Boost-Dokumente gegraben und konnte keine Empfehlungen finden. Hier lernen Sie heute etwas Neues!

+1

Leute könnten mir hier widersprechen, aber ich habe nie in meinem Leben entlang der Linien von "Gedächtnis ist billig" codiert. Speicher zu kaufen ist nicht unbedingt teuer im Vergleich zu früher, aber es ist sehr ähnlich wie Geld. Je mehr Sie haben, desto mehr verbringen Sie. Jedes Speicherupgrade, das ich mir für meinen Computer gekauft habe, habe ich jetzt ziemlich ausgereizt, da ich mehr Sachen "rennen kann". Ich habe immer versucht, in dieser Hinsicht konservativ zu schreiben, weil es für meine Bewerbung nicht unbedingt billig * ist. Wie auch immer, nur meine 2c auf dem :) –

+0

Ich stimme zu 100%! Und das ist der ganze Grund, warum ich diese Frage stelle. Ich habe nur diesen Kommentar rausgeschmissen, um irgendjemanden davon abzuhalten zu sagen: "Wen kümmert es, leg einfach 1k zu und sei damit fertig." Ich werde versuchen, es in der Post klarer zu machen. –

+0

Ah ok :) "Manche argumentieren" ist viel besser! –

Antwort

8

Von this paragraph der Dokumentation:

Der Speicher-Algorithmus ist ein Objekt, das in dem ersten Bytes eines Shared Memory/Speicher abgebildeten Datei Segment platziert wird.

Aufbau des Speichersegment:

____________ __________ ____________________________________________ 
|   |   |           | 
| memory | reserved | The memory algorithm will return portions | 
| algorithm |   | of the rest of the segment.    | 
|____________|__________|____________________________________________| 

Die Bibliothek verfügt über einen zusätzlichen Speicher-Overhead zu Beginn des Segmentes zu sitzen, damit ein paar Bytes Ihrer angeforderten Größe einnimmt. Nach this post und this post, diese genaue Anzahl der zusätzlichen Bytes nicht ermittelt werden kann:

Sie es nicht berechnen kann, weil es Speicherzuweisung bookeeping sind und Fragmentierungsprobleme, die in Laufzeit auf Ihrem Zuordnung je ändern/Deallokationsmuster. Und gemeinsam genutzte Speicher wird von Seiten durch das Betriebssystem (4K auf Linux 64k auf Fenstern) zugeordnet, so wird jede Zuordnung in der Praxis zugeordnet gerundet sein, um eine Seite:

managed_shared_memory segment(create_only, "name", 20); 

den gleichen Speicher verschwenden, wie :

managed_shared_memory segment(create_only, "name", 4096); 
+0

Gute Arbeit, diesen alten Posten zu finden; Ich suchte eine ganze Weile und kam trocken auf. Also, mit "in der Tat" meinst du, dass es keine konkrete Antwort gibt? Das bekomme ich von Ion Gaztañagas Antwort ... Danke auch für diesen Link zu den Boost-Dokumenten. Die Speicherkarten-ASCII-Kunst hilft, obwohl ich kein Glück hatte, programmatisch den "Speicheralgorithmus" + "reserviert" zu bestimmen. Aber letztlich ist es ein strittiger Punkt, da meine tatsächliche Implementierung 5-10 Strukturinstanzen speichert (auch von Gaztañaga erwähnt). Dennoch scheint dies eine gültige Frage zu sein, auch wenn es meistens "akademisch" ist. –

+0

Ah, * da * wir gehen. Ich wusste, dass die OS-Seitengröße ein relevantes Detail sein muss; Das obige Zitat bestätigt meinen Verdacht. Es sieht so aus, als hätte die "Best Rate" -Zuordnung zu tun. Danke noch einmal. –

2

So etwas wie die Werke OS'es Speicherseitengröße verwenden. In meinem Fall funktioniert das ..

off_t size = sizeof(class1) + (sizeof(class2) * 3); 
// round up to the OS page size. 
long page_size = sysconf(_SC_PAGE_SIZE); 
size = ((size/page_size) + (size % page_size ? 1 : 0)) * page_size; 

Mit boost :: managed_shared_memory können Sie Objekte im resultierenden Raum erstellen. Etwas wie ....

shared_memory_object::remove(m_name.c_str()); 
m_shared.reset(new managed_shared_memory(create_only, "myspace", size)); 
m_class1 = m_shared->construct<class1>("class1")(); 
m_class2 = m_shared->construct<class2>("class2")[3](); 
+0

+1 Ich mag die Idee, die Seitengröße des Systems aufzurunden. Es sieht jedoch immer noch so aus, als würden wir eine ** beliebige Menge an Padding ** erstellen. In diesem Fall "3" - dreimal "sizeof (class2)". Hab ich recht? Seitdem bin ich zu anderen Projekten übergegangen, aber ich bin immer noch daran interessiert, den gemeinsamen Speicher mit der geringsten Menge an Verschwendung zuzuweisen. –

+0

kann ich sowieso nicht sehen, um die Seitengröße für den gemeinsamen Speicherbereich zu umgehen. (Ein Fehler im zweiten Bit des Codes wurde behoben.) Sie können jedoch die Art der Unterzuweisung, die ich im zweiten Bit des Codes im Shared Memory-Bereich verwendet habe. Blick auf http://en.highscore.de/cpp/boost/interprocesscommunication.html#interprocesscommunication_managed_shared_memory gibt eine ziemlich gute Vorstellung von den vielen Möglichkeiten, wie Unterverteilung vorgenommen werden kann. Ich sollte diesen Editor besser lernen, damit ich sauberer verlinken kann * seufz * – lprent