2010-11-12 17 views
11

Szukam ostatecznej odpowiedzi (jeśli takowa istnieje) na ile pamięci powinno być przydzielone podczas tworzenia statycznych fragmentów pamięci współdzielonej przez boost::interprocess 's managed_shared_memory. Nawet official examples wydaje się przydzielać arbitrarily large porcji pamięci.Ile pamięci powinna przydzielić "managed_shared_memory"? (boost)

Rozważmy następującą strukturę:

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

My pierwsza reakcja jest odpowiedniej wielkości będą 8 bajtów, lub sizeof(Point2D). To niestety kończy się niepowodzeniem, gdy próbuję skonstruować obiekt, dając mi błędy seg-fault w czasie wykonywania.

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

Jaka operacja odczytu/zapisu powoduje błędy segmentu? Operacje na stosie? Tymczasowe alokacje w ramach segment.construct()? Ile dodatkowego jest konieczne przy przydzielaniu pamięci współużytkowanej?

Dzięki próbom i błędom odkryłem, że pomnożenie rozmiaru przez 4 może działać dla powyższej struktury, ale rozpada się, gdy zaczynam dodawać kolejne pola do mojego struct. Tak, to cuchnie złym hackem.

Niektórzy mogą twierdzić, że "pamięć jest tania" w nowoczesnym komputerze, ale nie zgadzam się z tą filozofią i nie lubię przydzielać więcej niż potrzebuję, jeśli mogę tego uniknąć. Wczoraj pobrałem dokumentację Boost i nie mogłem znaleźć żadnych rekomendacji. Oto nauka dzisiaj czegoś nowego!

+1

Ludzie mogą się ze mną nie zgodzić, ale nigdy w życiu nie zakodowałem na zasadzie "pamięć jest tania". Kupowanie pamięci niekoniecznie jest drogie w porównaniu do tego, jak było kiedyś, ale jest bardzo podobne do pieniędzy. Im więcej masz, tym więcej wydajesz. Każda aktualizacja pamięci, którą kupiłem dla mojego komputera, osiągnąłem maksimum dość szybko, teraz mogę "uruchomić więcej rzeczy". Zawsze starałem się kodować konserwatywnie pod tym względem, ponieważ niekoniecznie jest to tanie * dla mojej aplikacji *. W każdym razie, właśnie mój 2c na tym :) –

+0

Zgadzam się 100%! I to jest ** cały ** powód, dla którego zadaję to pytanie. Rzuciłem tylko tamten komentarz, aby odwieść kogoś, kto mówi: "kogo to obchodzi, po prostu przydziel 1k i skończ z tym." Postaram się wyjaśnić to lepiej w poście. –

+0

Ah ok :) "Niektórzy mogą argumentować" jest znacznie lepszy! –

Odpowiedz

8

Od this paragraph dokumentacji:

Algorytm pamięci jest obiektem, który umieszcza w pierwszych bajtów z pamięci współdzielonej pliku/pamięci mapowane segmencie.

Układ segmentu pamięci:

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

Biblioteka posiada dodatkową pamięć napowietrznych siedzi na początku odcinka, tym samym zajmując kilka bajtów swojej żądanej wielkości. Według this post i this post, dokładna liczba dodatkowych bajtów nie można określić:

nie można obliczyć, ponieważ nie są pamięci bookeeping przydział i problemy fragmentacji, które zmieniają się w wykonywania w zależności od przydziału /Wzór zwolnienia. I wspólna pamięć jest przydzielana przez stron przez system operacyjny (4K na Linuksie 64k na Windows), więc każdy przydział będzie w praktyce przydzielonego zaokrąglone stronie:

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

będą tracić taką samą pamięć jak :

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

Dobra robota, znalezienie tego starego posta; Szukałem dość długo i wyszedłem na sucho. Tak więc przez "rzeczywiście" masz na myśli to, że ** nie ma konkretnej odpowiedzi? ** Tak właśnie otrzymuję odpowiedź Iona Gaztañagi ... Dziękuję również za to łącze do dokumentów Boost. Mapa pamięci ASCII pomaga, choć nie miałem szczęścia w programowym określaniu "algorytmu pamięci" + "zarezerwowanego". Ale ostatecznie jest to kwestią sporną, ponieważ moja obecna implementacja przechowuje 5-10 instancji struktury (również wspomnianych przez Gaztañaga). Mimo to wydaje się, że jest to prawidłowe pytanie, nawet jeśli jest ono w większości "akademickie". –

+0

Ach, * tam * idziemy. Wiedziałem, że rozmiar strony OS musi być istotnym szczegółem; powyższy cytat potwierdza moje podejrzenia. Wygląda na to, że trzeba będzie przydzielić "najlepsze przypuszczenie". Dzięki jeszcze raz. –

2

Coś Korzystanie z pamięci OS'es prace rozmiaru strony. W moim przypadku to działa ..

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; 

Korzystanie boost :: managed_shared_memory pozwala na budowę obiektów w powstałej przestrzeni. Coś jak ...

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 Podoba mi się pomysł zaokrąglania do rozmiaru strony systemowej. Jednak wciąż wygląda na to, że tworzymy ** dowolną liczbę wypełnień **. W tym przypadku "3" - trzy razy "sizeof (class2)". Mam rację? Od tego czasu przeszedłem do innych projektów, ale nadal jestem zainteresowany najlepszym sposobem przydzielania pamięci współdzielonej przy jak najmniejszej ilości odpadów. –

+0

Nie widzę żadnej okazji, aby obejść rozmiar strony dla obszaru pamięci współużytkowanej. (Naprawiono błąd w drugim bicie kodu.) Można jednak wykonać typ alokacji, której użyłem w drugim bicie kodu wewnątrz obszaru pamięci wspólnej. Spójrz na http://en.highscore.de/cpp/boost/interprocesscommunication.html#interprocesscommunication_managed_shared_memory daje całkiem niezły pomysł na wiele sposobów, które można przydzielić alokacji podrzędnej. Lepiej nauczę się tego edytora, dzięki czemu mogę połączyć więcej czysto * westchnienie * – lprent

Powiązane problemy