2010-04-18 9 views
15

Państwa C++ 0x FCD w charakterze 23.3.6.2 wektora:Dlaczego shrink_to_fit nie jest wiążący?

void shrink_to_fit(); 

Uwagi: shrink_to_fit jest niewiążące żądanie zmniejszenia mocy() na wielkość(). [Uwaga: Żądanie nie jest wiążące, aby umożliwić szerokość geograficzną dla optymalizacji związanych z realizacją. — koniec notatki]

Jakie optymalizacje są dozwolone?

+13

Mogę sobie wyobrazić, że niektóre przydzielające mogą chcieć przydzielić w blokach o stałej długości. Zatem jeśli rozmiar elementu jest mniejszy niż ten rozmiar bloku, może on nadal się przeorganizować. Tylko zgadnij ... –

+1

@Johannes: Jeśli napisałeś to jako odpowiedź, byłoby o wiele łatwiej wyjaśnić. Zobacz mój komentarz do podwójnego poniżej, a także nie widzę, jak alokator może komunikować, że do wektora (allocate() zwraca tylko wskaźnik), ale przypuszczam, że może to być częściowo wyspecjalizowane, jeśli std :: allocator jest używany. Mimo to zastanawiam się nad specjalizacjami użytkownika (nadal dozwolone, prawda?) I konfliktami. –

Odpowiedz

11

Jest to dość napięte na zewnątrz, ale:

Rozważmy przydzielania wektor, które mogłyby jedynie przydzielić pamięci z, powiedzmy, 4 KB szczegółowości. Wtedy nie byłoby sensu ponownie przydzielać pamięci, jeśli wektor miał pojemność 4096 i rozmiar 4095, ponieważ nie oszczędziłoby to pamięci, ale marnowałoby trochę czasu procesora na kopiowanie elementów.

+0

Możliwe, ale w interfejsie standardowego przydziału nie ma sposobu na przekazanie tego. (Chyba że brakowało mi dodania 0x?) Nie zmieniając przydziału, jeśli rozmiar wynosi 4095, a pojemność 4096 może być zrobiona niezależnie, i przypuszczam, że ma sens - z tym wyjątkiem, że mogę to sprawdzić, jeśli chcę przed wywołaniem shrink_to_fit. –

+0

Cóż, jednym z wyspecjalizowanych przypadków jest wektor . Alokatory oczywiście mają co najmniej 1-bajtową ziarnistość i, o ile pamiętam, wektor używa pewnego bitu na element. Naprawdę niewielkie. – doublep

+0

wektor jest obrzydliwością ogólnie przyjętą za pomyłkę.Powoduje to problemy, jeśli napiszesz szablon, który może używać Bool i oczekujesz prawdziwego interfejsu kontenera, i mam nadzieję, że żadne inne specjalizacje dla wektorów nie mogą być podobnie złamane (w rzeczywistości, AFAIK, standard zabrania tego). –

4

Pomysły zaokrąglania są rzeczywiście istotne, ale raczej pośrednio. Pytanie brzmi "jakie optymalizacje mają być dozwolone". To czyni pewne założenia dotyczące procesu standaryzacji. optymalizacje. Ogólnie rzecz biorąc, celem jest zezwolenie na wszystkie nieobserwowalne optymalizacje, a następnie na niektóre - na przykład na kopiowanie, w ramach którego można zaobserwować niedoszne wykonywanie kopii. W tym przypadku, capacity() != size() może być obserwowalnym efektem optymalizacji, a standard pozwala na to.

Jeśli chodzi o powody dodania tej szerokości geograficznej, mógłbym również wyobrazić sobie ignorowanie żądania zmniejszenia, gdy capacity() jest tylko 101% z - zbyt mało zysków. Nigdy nie będzie żadnego konkretnego powodu, ponieważ LWG składa się z wielu osób o wielu poglądach. Po prostu istnieje konsensus co do tego, że istnieją wystarczające możliwości optymalizacji stworzone przez przyznanie tej wolności.

+0

Wiem, że ogólnie rzecz biorąc, standard próbuje umożliwić implementacjom wybór spośród wielu różnych i konkurencyjnych optymalizacji. Biorąc pod uwagę wyraźną uwagę, myślałem, że mogą być pewne konkretne, i mam nadzieję, że coś więcej niż "prosiliście o to działanie i nie zgadzamy się, status: odrzucono". –

0

Kiedy to jest już specjalne, wektor < bool> należy przydzielić w blokach o rozmiarze 8. Wiem też, że niektórzy ludzie pracują nad uzyskaniem malloc, aby zwrócić "prawdziwy rozmiar" wszystkich przydzielonych bloków, więc jeśli przydzielony blok wprowadziłby nieuniknione odpady, zamiast tego wektor użytecznie wykorzystuje przestrzeń.

Gdy przechodzimy do 64-bitowych systemów operacyjnych, przestrzeń pamięci nagle staje się (słynne ostatnie słowa) większa niż ktokolwiek, kto kiedykolwiek zbliży się do wypełnienia, więc rozsądniej jest przydzielić duże bloki pamięci wirtualnej i wypełnić je za każdym razem. Przenoszenie obiektów dookoła jest kosztowne, aw praktyce stratą czasu, ponieważ nie poruszamy się, ponieważ pamięć fizyczna jest ograniczona, tylko z jednego wirtualnego miejsca do drugiego!

+0

Jak to się ma do możliwych optymalizacji włączonych przez shrink_to_fit jako niewiążące? –

+0

Bo jeśli wektor został zmuszony do zrobienia shrink_to_fit, nawet jeśli miał dodatkową pamięć, której nie mógł się pozbyć, to skończyłoby się relokowanie, lub po prostu "ponowne odkrycie" tej pamięci później, kosztem. Lepiej, żeby to było z góry i powiedz: "Nie mogę zmniejszyć mojego bufora mniejszego niż to, bez marnowania pamięci". –

Powiązane problemy