2010-11-12 14 views
11

Sto cercando una risposta definitiva (se effettivamente ne esiste una) su quanta memoria deve essere allocata quando si creano blocchi statici di memoria condivisa tramite managed_shared_memoryboost::interprocess. Anche official examples sembra allocare blocchi di memoria arbitrarily large.Quanta memoria deve allocare "managed_shared_memory"? (boost)

consideri la seguente struttura:

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

mia reazione iniziale è che la dimensione necessaria sarebbe 8 byte, o sizeof(Point2D). Questo fallisce miseramente quando tento di costruire un oggetto, dandomi errori di seg in runtime.

// BAD: 8 bytes is nowhere near enough memory allocated. 
managed_shared_memory segment(create_only, "My shared memory", sizeof(Point2D)); 

Quale operazione di lettura/scrittura sta causando errori seg.? Operazioni di stack? Assegnazioni temporanee entro segment.construct()? Quanto sovraccarico è necessario quando si assegna memoria condivisa?

Per tentativi ho rilevato che moltiplicare la dimensione per 4 può funzionare per la struttura precedente, ma si riduce quando aggiungo altri campi al mio struct. Quindi, puzza di un brutto attacco.

Alcuni potrebbero obiettare che "la memoria è a buon mercato" nel PC moderno, ma non sono d'accordo con questa filosofia e non mi piace allocare più del necessario, se posso evitarlo. Ho esaminato i documenti Boost ieri e non sono riuscito a trovare alcun suggerimento. Ecco per imparare qualcosa di nuovo oggi!

+1

Le persone potrebbero non essere d'accordo con me qui, ma non ho mai scritto nella mia vita sulla falsariga di "la memoria è economica". L'acquisto di memoria non è necessariamente costoso rispetto a come era una volta, ma è molto simile al denaro. Più hai, più spendi. Ogni aggiornamento di memoria che ho acquistato per il mio computer, ho raggiunto il limite massimo ora che posso "eseguire più cose". Ho sempre cercato di codificare in modo conservativo in questo senso, perché non è necessariamente economico * per la mia applicazione *. Comunque, solo il mio 2c su quello :) –

+0

Sono d'accordo al 100%! E questa è la ** completa ** ragione per cui sto facendo questa domanda. Ho solo buttato fuori quel commento per dissuadere chiunque dicesse "a chi importa, basta assegnare 1k e averne fatto." Proverò a renderlo più chiaro nel post. –

+0

Ah ok :) "Qualcuno potrebbe obiettare" è molto meglio! –

risposta

8

Da this paragraph della documentazione:

L'algoritmo di memoria è un oggetto che è posto nei primi byte di un file memoria condivisa/memoria mappata segmento.

layout del segmento di memoria:

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

La biblioteca dispone di una memoria aggiuntiva in testa seduto al all'inizio del segmento, occupando così alcuni byte del vostro formato richiesto. Secondo this post e this post, questo numero esatto di byte aggiuntivi non può essere determinato:

Non è possibile calcolare, perché ci sono la memoria di allocazione bookeeping e problemi di frammentazione che cambiano in runtime a seconda della ripartizione /modello di deallocazione. E memoria condivisa è allocato pagine nel sistema operativo (4K su Linux 64k su finestre), in modo che qualsiasi allocazione sarà in pratica assegnato arrotondato a una pagina :

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

sarà sprecare la stessa memoria :

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

Buon lavoro a trovare quel vecchio post; Ho cercato per un po 'e mi sono ritrovato asciutto. Quindi, per "effettivamente" intendi che ** non c'è una risposta concreta? ** Questo è ciò che ottengo dalla risposta di Ion Gaztañaga ... Inoltre, grazie per il link ai documenti Boost. L'arte ASCII della mappa di memoria aiuta, anche se non ho avuto fortuna nel determinare in modo programmatico l'algoritmo di memoria + 'riservato'. Ma alla fine, è un punto controverso dal momento che la mia implementazione effettiva memorizza 5-10 istanze di struttura (citato anche da Gaztañaga). Tuttavia, questa sembra una domanda valida, anche se per lo più è "accademica". –

+0

Ah, * ci * andiamo. Sapevo che le dimensioni della pagina del sistema operativo devono essere un dettaglio pertinente; la citazione sopra conferma i miei sospetti. Sembra che l'allocazione "best guess" dovrà fare. Grazie ancora. –

2

Qualcosa di simile utilizzando le opere della pagina di memoria OS'es. Nel mio caso questo funziona ..

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; 

Utilizzando boost :: managed_shared_memory consente di creare oggetti nello spazio risultante. Qualcosa come ...

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 Mi piace l'idea di arrotondare alle dimensioni della pagina del sistema. Tuttavia, sembra ancora che stiamo creando una ** quantità arbitraria di padding **. In questo caso "3" - tre volte 'sizeof (class2)'. Ho ragione? Da allora mi sono spostato su altri progetti, ma sono ancora interessato al modo migliore di allocare la memoria condivisa con il minimo spreco. –

+0

Non riesco a vedere comunque di andare in giro usando le dimensioni della pagina per l'area di memoria condivisa. (Risolto un bug nel secondo bit di codice.) Tuttavia si può fare il tipo di suballocazione che stavo usando nel secondo bit di codice all'interno dell'area di memoria condivisa. guardare http://en.highscore.de/cpp/boost/interprocesscommunication.html#interprocesscommunication_managed_shared_memory dà una buona idea dei molti modi in cui è possibile eseguire la sub-allocazione. Farò meglio a imparare questo editor in modo da poter collegare in modo più pulito * sospiro * – lprent