Czy zarządzanie pamięcią w programowaniu staje się nieistotne?

38

Tło
Odwiedziłem starą (ale świetną) stronę, na której nie byłem od wieków - Alioth Language Shootout ( http://benchmarksgame.alioth.debian.org/ ).

Zacząłem programować w C / C ++ kilka lat temu, ale od tego czasu pracuję prawie wyłącznie w Javie z powodu ograniczeń językowych w projektach, w których byłem zaangażowany. Nie pamiętając liczb, chciałem zobaczyć, w przybliżeniu, jak dobrze Java poradził sobie z C / C ++ pod względem zużycia zasobów.

Te czasy wykonania były nadal stosunkowo dobra, z Java w najgorszym wykonywania 4x wolniej niż C / C ++, ale średnio około (lub poniżej) 2x. Z uwagi na naturę implementacji samej Javy nie było to zaskoczeniem, a jej wydajność była w rzeczywistości niższa niż się spodziewałem.

Prawdziwą cegłą był przydział pamięci - w najgorszym przypadku Java przydzieliła:

  • aż 52 razy więcej pamięci niż C.
  • i 25 razy więcej niż C ++.

52x pamięć ... Absolutnie paskudna, prawda? ... Albo to jest? Pamięć jest teraz stosunkowo tania.

Pytanie:
Jeśli nie mówimy o platformach docelowych z surowymi ograniczeniami pamięci operacyjnej (tj. Systemy wbudowane i tym podobne), czy użycie pamięci powinno być problemem przy dzisiejszym wyborze języka ogólnego?

Pytam częściowo, ponieważ rozważam migrację do Scali jako mojego głównego języka. Bardzo podoba mi się jego funkcjonalny aspekt, ale z tego, co widzę, jest jeszcze droższy pod względem pamięci niż Java. Ponieważ jednak z roku na rok pamięć wydaje się coraz szybsza, tańsza i obfitsza (wydaje się, że coraz trudniej jest znaleźć laptopa konsumenckiego bez co najmniej 4 GB pamięci RAM DDR3), czy nie można argumentować, że zarządzanie zasobami staje się coraz bardziej nieistotne w porównaniu z (prawdopodobnie kosztownymi pod względem implementacji) funkcjami języka wysokiego poziomu, które pozwalają na szybszą budowę bardziej czytelnych rozwiązań?

csvan
źródło
32
Nie zapominaj, że tylko dlatego, że Java przydziela 52 razy więcej pamięci niż C dla małego testu porównawczego, nie oznacza to, że zużyje 52 razy więcej pamięci dla dużej aplikacji. Lwia część tej pamięci będzie stałą ilością wymaganą przez JVM, a im większa aplikacja, tym mniej znacząca będzie ta część.
Carson63000,
4
Jeśli tworzenie aplikacji mobilnych jest nieistotne, to tak.
JeffO,
3
Pytanie brzmi, jak zły jest test porównawczy Java w porównaniu do C / C ++ i co to oznacza, jeśli chodzi o wybór między dwoma językami. Widzę, że jest to tematyczne, istotne dla wszystkich programistów, jasne, skoncentrowane i możliwe do uzyskania rozsądnych odpowiedzi w obecnej formie. Głosowałem za ponownym otwarciem.
GlenPeterson
Większość problemów z wydajnością jest powodowanych i naprawianych na poziomie projektu, a nie na poziomie narzędzia. Niektóre problemy wymagają ziarnistości 1ms i dlatego wymagają C / C ++. Jeśli masz swobodę, na przykład 10ms, być może Scala lub Java to dobra opcja. Większość kontrolerów wejściowych do gier działa na poziomie 50-100 ms. Wiele osób pisze dziś krytyczne sekcje w jednym języku, a resztę programu w innym.
GlenPeterson
4
Patrząc na „25x więcej niż C ++” w tym teście należy wziąć pod uwagę ciągłe dodawanie czasu wykonywania (około 13 Mb). W miarę narastania problemu zapotrzebowanie na pamięć wykonawczą zmniejsza się jako procent całego programu. Tam, gdzie użycie pamięci C ++ jest mniejsze niż 1 MB, jeśli odejmiesz użycie pamięci C ++ od użycia pamięci Java, otrzymasz dość stałą wartość.

Odpowiedzi:

34

Zarządzanie pamięcią jest niezwykle istotne, ponieważ decyduje o tym, jak szybko coś się pojawia, nawet jeśli coś ma dużo pamięci. Najlepszym i najbardziej kanonicznym przykładem są gry z tytułem AAA, takie jak Call of Duty lub Bioshock. Są to aplikacje działające w czasie rzeczywistym, wymagające ogromnej kontroli w zakresie optymalizacji i użytkowania. Problemem nie jest samo użycie, ale zarządzanie.

Wszystko sprowadza się do dwóch słów: Garbage Collection. Algorytmy wyrzucania elementów bezużytecznych mogą powodować niewielkie problemy z wydajnością, a nawet powodować zawieszanie się aplikacji przez sekundę lub dwie. Głównie nieszkodliwy w aplikacji księgowej, ale potencjalnie rujnujący pod względem doświadczenia użytkownika w grze Call of Duty. Dlatego w aplikacjach, w których liczy się czas, języki odśmiecane mogą być bardzo problematyczne. Jest to na przykład jeden z celów projektowych Squirrel, który stara się zaradzić problemowi, jaki ma Lua z GC, stosując zamiast tego liczenie referencji.

Czy to bardziej ból głowy? Jasne, ale jeśli potrzebujesz precyzyjnej kontroli, godzisz się z tym.

Inżynier świata
źródło
14
-1 „... dosłownie śmiertelnie niebezpieczna w grze ...” - Moja codzienna praca to system krytyczny dla bezpieczeństwa, tak jak dla bezpieczeństwa życia. Najgorsze, co dzieje się w oprogramowaniu do gier, jest takie, że pisarz popada w ruinę, ponieważ jest gówniany i nikt go nie kupuje. To różnica, której nie należy bagatelizować.
mattnz
4
@mattnz Zły wybór słów z mojej strony. Zostało to naprawione. Nie miałem zamiaru niczego trywializować.
Inżynier świata
19
@Mattnz: Jeśli znasz gry, to oczywiście oznacza, że może to być śmiertelne dla twojej postaci , co jest całkowicie prawdą.
Mason Wheeler,
8
+1, ponieważ osoba odpowiadająca ma diament, więc odpowiedź musi być poprawna.
psr
8
Śmieciarki w czasie rzeczywistym istnieją od wieków.
Jörg W Mittag
30

Prawdziwą cegłą był przydział pamięci - w najgorszym przypadku Java przyznała aż 52 razy więcej pamięci niż C i 25 razy więcej niż C ++.

Czy rozumiesz liczby, na których opierasz swoje pytanie?

  • Ile pamięci zostało przydzielone?
  • Co robiły programy?

Kiedy występuje duża rozbieżność między tymi programami Java i C, jest to głównie domyślny przydział pamięci JVM w porównaniu do wszystkiego, czego potrzebuje libc:


  • Program Java n-body 13 996 KB :: program C 320 KB :: Darmowy Pascal 8 KB

Spójrz na zadania wymagające przydzielenia pamięci (lub użyj dodatkowych buforów do gromadzenia wyników z programów wielordzeniowych):


  • program Java mandelbrot 67 , 880KB :: program C 30 , 444 KB

  • k-nukleotydowy
    program Java 494 , 040KB :: program C 153 , 452KB


  • program Java 511 , 484KB z komplementacją wsteczną :: program C 248 , 632KB

  • regex-dna
    program Java 557 , 080KB :: program C 289 , 088KB

  • drzewa binarne
    program Java 506 , 592KB :: program C 99 , 448KB

... czy użycie pamięci powinno dziś stanowić problem?

Zależy to od tego, czy określone użycie, dla twojego konkretnego podejścia do rozwiązania określonych problemów, które musisz rozwiązać, będzie ograniczone przez określone limity dostępnej pamięci na konkretnej platformie, która będzie używana.

igouy
źródło
3
Twoja uwaga na temat zagłębiania się w liczby jest słuszna, a ta strona z pewnością ma sporo zastrzeżeń dotyczących ich testów. Twoja odpowiedź zostałaby wzmocniona poprzez bezpośrednie odniesienie się do podstawowego pytania, którym jest „czy korzystanie z pamięci powinno być problemem?”
1
Doskonała odpowiedź, że uratowano stosunkowo słabe pytanie (niejasno określony punkt odniesienia jest nawet gorszy niż przedwczesna optymalizacja :). Dane, które wspierają analizę, są dobrze przedstawione, konkretne i stanowią świetne do myślenia. Zdecydowanie warte nagrody za „przykładową odpowiedź” .
komara
17

Jak w przypadku wszystkich rzeczy, jest to kompromis.

Jeśli budujesz aplikację, która będzie działała na pulpicie jednego użytkownika i można zasadnie oczekiwać, że będzie kontrolować dużą część pamięci RAM na tym komputerze, warto poświęcić użycie pamięci dla szybkości implementacji. Jeśli celujesz w tę samą maszynę, ale budujesz małe narzędzie, które będzie konkurować z wieloma innymi wymagającymi pamięci aplikacjami, które działają jednocześnie, możesz być bardziej ostrożny w kwestii tego kompromisu. Użytkownikowi może się spodobać gra, która potrzebuje całej pamięci, gdy jest uruchomiona (choć, jak zauważa World Engineer, „ Będę się martwił, jeśli śmieciarz zdecyduje się okresowo wstrzymać akcję, aby wykonać zamiatanie) - prawdopodobnie będą o wiele mniej entuzjastycznie nastawieni, jeśli odtwarzacz muzyczny uruchamiany w tle podczas wykonywania innych czynności zdecyduje się pożreć masę pamięci i zakłóca ich zdolność do pracy. Jeśli budujesz aplikację internetową, dowolna pamięć używana na serwerach ogranicza twoją skalowalność, zmuszając Cię do wydawania większych pieniędzy na więcej serwerów aplikacji w celu obsługi tego samego zestawu użytkowników. Może to mieć duży wpływ na ekonomikę firmy, więc możesz być bardzo ostrożny przy podejmowaniu tego kompromisu. dowolna pamięć używana na serwerach ogranicza twoją skalowalność, zmuszając Cię do wydawania większej ilości pieniędzy na więcej serwerów aplikacji w celu obsługi tego samego zestawu użytkowników. Może to mieć duży wpływ na ekonomikę firmy, więc możesz być bardzo ostrożny przy podejmowaniu tego kompromisu. dowolna pamięć używana na serwerach ogranicza twoją skalowalność, zmuszając Cię do wydawania większej ilości pieniędzy na więcej serwerów aplikacji w celu obsługi tego samego zestawu użytkowników. Może to mieć duży wpływ na ekonomikę firmy, więc możesz być bardzo ostrożny przy podejmowaniu tego kompromisu.

Justin Cave
źródło
8

To zależy od wielu czynników, zwłaszcza od skali, w jakiej pracujesz.

Dla celów argumentu załóżmy 30-krotną różnicę w pamięci i 2x w wykorzystaniu procesora.

Jeśli masz do czynienia z programem interaktywnym, który zajmuje 10 megabajtów pamięci i 1 milisekundę procesora, jeśli jest napisany w C, jest to prawie nieistotne - 300 megabajtów pamięci i 2 milisekundy do wykonania jest zwykle zupełnie nieistotne na typowym pulpicie, i mało prawdopodobne, by miało to znaczenie nawet na telefonie lub tablecie.

Różnica między potrzebowaniem około połowy zasobów 1 serwera a potrzebowaniem 15 serwerów jest jednak znacznie większym krokiem - zwłaszcza, że ​​skalowanie do 15 serwerów prawdopodobnie będzie wymagało dużo dodatkowej pracy, a nie mniej. Jeśli chodzi o przyszłą ekspansję, te same czynniki, o których wspominasz, sugerują, że jeśli twoja baza klientów nie ulegnie znacznemu wzrostowi, że jeśli będzie działać na jednym serwerze, istnieje spora szansa, że ​​kiedy wyrosniesz z tego serwera, będziesz w stanie zastąpić to jednym nowym serwerem bez żadnego problemu.

Innym czynnikiem, który naprawdę musisz wziąć pod uwagę, jest dokładnie to, ile różnic w kosztach rozwoju zobaczysz dla swojego konkretnego zadania. W tej chwili zasadniczo patrzysz na jedną stronę równania. Aby dobrze zorientować się w kosztach i korzyściach, (oczywiście) musisz przyjrzeć się zarówno kosztom, jak i korzyściom, a nie pojedynczo. Prawdziwe pytanie brzmi: „czy x jest większy niż y?” - ale nie można tego ustalić, patrząc tylko na x. Oczywiście musisz również spojrzeć na y.

Jerry Coffin
źródło
2
+1 za zauważenie skali. Przeczytaj ten artykuł, aby naprawdę zrozumieć zarządzanie zasobami na dużą skalę.
Guy Coder,
6

Zarządzanie pamięcią jest absolutnie istotne w dzisiejszym świecie. Jednak nie tak, jak można się spodziewać. Nawet w językach, w których zbierane są śmieci, musisz upewnić się, że nie wyciek referencji

Robisz coś złego, jeśli to jest twój kod:

static List<string> Cache;

...
Cache.Add(foo); //and then never remove anything from Cache

Odśmiecanie nie może magicznie wiedzieć, że nigdy nie użyjesz jakiegoś odniesienia, chyba że go stworzysz, więc nie będziesz mógł go użyć ponownie, tzn. Robiąc Cache=nullto skutecznie ostrzegasz śmieciarza, że ​​„hej, nie będę mógł uzyskaj do niej dostęp. Zrób z tym, co chcesz ”

Jest to bardziej skomplikowane, ale wycieki referencyjne są tak samo, jeśli nie bardziej, szkodliwe niż tradycyjne wycieki pamięci.

Istnieją również miejsca, w których nie można zmieścić pojemnika na śmieci. Na przykład ATTiny84 jest mikrokontrolerem z 512 bajtami kodu ROM i 32 bajtami RAM. Powodzenia! To ekstremalne zjawisko i prawdopodobnie nie byłoby programowane w niczym innym niż w asemblerze, ale nadal. W innych przypadkach możesz mieć 1M pamięci. Jasne, możesz zmieścić śmietnik, ale jeśli procesor jest bardzo wolny (albo z powodu ograniczeń, albo w celu oszczędzania baterii), to nie będziesz chciał używać śmieciarza, ponieważ śledzenie tego, co programista może wiedzieć, jest zbyt drogie .

Staje się również znacznie trudniejsze w używaniu funkcji wyrzucania elementów bezużytecznych, gdy potrzebujesz gwarantowanych czasów odpowiedzi. Na przykład, jeśli masz monitor pracy serca lub coś takiego, a gdy odbiera on sygnał 1z jakiegoś portu, musisz zagwarantować, że możesz zareagować na niego odpowiednim sygnałem lub czymś w ciągu 10ms. Jeśli w trakcie rutynowej odpowiedzi moduł odśmiecający musi wykonać przepustkę, a odpowiedź zajmuje 100 ms, może to oznaczać, że ktoś nie żyje. Zbieranie śmieci jest bardzo trudne, jeśli nie niemożliwe, do wykorzystania, gdy należy zagwarantować wymagania dotyczące czasu.

I oczywiście, nawet na nowoczesnym sprzęcie, są przypadki, w których potrzebujesz dodatkowych 2% wydajności, nie martwiąc się o narzut śmieciarki.

Earlz
źródło
3

Jak powiedział Donald Knuth, przedwczesna optymalizacja jest źródłem wszelkiego zła. Jeśli nie masz powodu, aby sądzić, że pamięć będzie wąskim gardłem, nie martw się o to. Biorąc pod uwagę, że prawo Moore'a wciąż zapewnia zwiększoną pojemność pamięci (chociaż nie uzyskujemy z niej szybszego kodu jednowątkowego), istnieją wszelkie powody, by sądzić, że w przyszłości będziemy jeszcze mniej ograniczeni w zakresie pamięci niż my są dzisiaj.

To powiedziawszy, jeśli optymalizacja nie jest przedwczesna, zrób to. Obecnie osobiście pracuję nad projektem, w którym bardzo szczegółowo rozumiem wykorzystanie pamięci, tak naprawdę potrzebuję precyzyjnej kontroli, a zamiatanie śmieci by mnie zabiło. Dlatego robię ten projekt w C ++. Ale wybór ten wydaje mi się wydarzeniem raz na kilka lat. (Mam nadzieję, że za kilka tygodni nie będę więcej dotykać C ++ przez kilka kolejnych lat.)

btilly
źródło
4
W ten sposób powstaje rozdęte oprogramowanie dla przedsiębiorstw na niewiarygodnie wolnych komputerach, które ciągle stronicują. Wszyscy mówią: „Pewnie, że moja aplikacja zajmuje więcej pamięci, ale kogo to obchodzi, jest praktycznie darmowa!” a następnie otrzymujesz pełen stos aplikacji wymagających pamięci, które sprawiają, że 4 GB pamięci RAM działa wolniej niż 512 MB pamięci RAM 10 lat temu.
MrFox,
@MrFox W rzeczywistości problem z oprogramowaniem korporacyjnym polega na tym, że ludzie, którzy decydują się na jego użycie, nie są tymi, którzy cierpią z tego powodu. Zobacz lists.canonical.org/pipermail/kragen-tol/2005-April/000772.html, aby uzyskać doskonały opis przyczyny jego uszkodzenia. Jeśli chodzi o resztę, czy nie zauważyłeś, że czasem martwię się o użycie pamięci?
btilly,
3

Dla osób zajmujących się „big data” zarządzanie pamięcią jest nadal ogromnym problemem. Programy astronomiczne, fizyki, bioinformatyki, uczenia maszynowego itp. Muszą radzić sobie z wielobajtowymi zestawami danych, a programy działają o wiele szybciej, jeśli odpowiednie części można zachować w pamięci. Nawet uruchomienie na komputerze z 128 GB pamięci RAM nie rozwiązuje problemu.

Jest także kwestia wykorzystania GPU, choć być może sklasyfikowałbyś to jako system wbudowany. Większość trudnego myślenia przy użyciu CUDA lub OpenCL sprowadza się do problemów z zarządzaniem pamięcią podczas przesyłania danych z pamięci głównej do pamięci GPU.

Charles E. Grant
źródło
1

Szczerze mówiąc, wiele Javy pozwala sobie na pewne prawdziwie i bezcelowe, klasowo wybuchowe wzorce, które po prostu mordują wydajność i pamięć świni, ale zastanawiam się, ile z tej pamięci to tylko JVM, która teoretycznie (heh) pozwala ci uruchomić ta sama aplikacja w wielu środowiskach bez konieczności przepisywania nowych. Stąd pytanie o kompromis w zakresie projektowania sprowadza się do: „Ile pamięci twoich użytkowników jest dla Ciebie warte takiego rozwoju?”

Jest to, IMO, warte rozważenia i warte rozważenia. Wkurza mnie jednak to, że ponieważ współczesne komputery PC są tak potężne, a pamięć tak tania, możemy całkowicie zignorować takie obawy i nadmuchać funkcje i nadęty kod oraz być leniwym w kwestii wyborów do tego stopnia, że ​​wydaje się, że jest dużo Robię teraz na komputerze z systemem Windows, zajmuje to tyle samo czasu, co w Windows '95. Poważnie, Word? Ile nowych bzdur, których 80% ich bazy użytkowników faktycznie potrzebuje, mogliby dodać w ciągu 18 lat? Jesteś pewien, że mieliśmy już okna sprawdzania pisowni, prawda? Ale rozmawialiśmy o pamięci, która niekoniecznie jest szybka, jeśli masz jej dużo, więc dygresuję.

Ale oczywiście, jeśli uda Ci się zrobić aplikację w ciągu 2 tygodni kosztem może kilku dodatkowych megabajtów zamiast 2 lat, aby uzyskać wersję wymagającą tylko kilku K, warto zastanowić się, jak wygląda kilka megabajtów ( Zgaduję) 4-12 koncertów na przeciętnym komputerze użytkownika, zanim wyśmiewam się z tego, że jestem taki niechlujny.

Ale co to ma wspólnego ze Scalą poza kwestią kompromisu? Tylko dlatego, że jest to zbieranie śmieci, nie oznacza, że ​​nie zawsze powinieneś myśleć o przepływie danych w kategoriach tego, co jest w zakresach i zamknięciach, oraz czy należy je zostawić siedząc lub używać w taki sposób, aby zwolniony przez GC, gdy nie jest już potrzebny. Jest to coś, o czym nawet my, twórcy stron WWW JavaScript, musieliśmy pomyśleć i mam nadzieję, że będzie to kontynuowane, gdy będziemy się rozprzestrzeniać w innych problematycznych domenach, takich jak rak doświadczony w perfekcji (że wszyscy powinniście byli zabić za pomocą Flasha lub apletów lub czegoś, gdy mieliście okazję) tym jesteśmy.

Erik Reppen
źródło
0

Czy zarządzanie pamięcią w programowaniu staje się nieistotne?

Zarządzanie pamięcią (lub sterowanie) jest właściwie głównym powodem, dla którego używam C i C ++.

Pamięć jest teraz stosunkowo tania.

Nie szybka pamięć. Nadal patrzymy na niewielką liczbę rejestrów, coś w rodzaju pamięci podręcznej 32 KB dla L1 na i7, 256 KB dla L2 i 2 MB dla L3 / rdzenia. To mówi:

Jeśli nie mówimy o platformach docelowych z surowymi ograniczeniami pamięci operacyjnej (tj. Systemy wbudowane i tym podobne), czy użycie pamięci powinno być problemem przy wyborze dzisiaj języka ogólnego przeznaczenia?

Zużycie pamięci na poziomie ogólnym, może nie. Jestem trochę niepraktyczny, ponieważ nie podoba mi się pomysł notatnika, który zabiera, powiedzmy, 50 megabajtów pamięci DRAM i setki megabajtów miejsca na dysku twardym, mimo że mam to do stracenia i więcej. Jestem tu od dłuższego czasu i wydaje mi się to dziwne i trochę obrzydliwe, gdy widzę, że tak prosta aplikacja zajmuje stosunkowo dużo pamięci na to, co powinno być możliwe w przypadku kilobajtów. To powiedziawszy, mógłbym być w stanie żyć ze sobą, gdybym spotkał się z taką rzeczą, jeśli nadal byłaby miła i wrażliwa.

Powodem, dla którego zarządzanie pamięcią jest dla mnie ważne w mojej dziedzinie, nie jest ogólne zmniejszenie zużycia pamięci. Setki megabajtów pamięci nie musi spowalniać aplikacji w żaden nietrywialny sposób, jeśli żadna z tych pamięci nie jest często uzyskiwana (np. Tylko po kliknięciu przycisku lub innej formie wprowadzania danych przez użytkownika, co jest niezwykle rzadkie, chyba że użytkownik mówią o koreańskich graczach Starcraft, którzy mogą kliknąć przycisk milion razy na sekundę).

Powodem, dla którego jest to ważne w mojej dziedzinie, jest ścisłe połączenie pamięci, które jest bardzo często dostępne (np. Zapętlanie każdej ramki) w tych krytycznych ścieżkach. Nie chcemy przegapić pamięci podręcznej za każdym razem, gdy uzyskujemy dostęp tylko do jednego z miliona elementów, do których wszystkie muszą być dostępne w pętli przy każdej klatce. Kiedy przenosimy pamięć w dół hierarchii od wolnej pamięci do szybkiej pamięci w dużych porcjach, powiedzmy 64 bajtowe linie pamięci podręcznej, naprawdę pomocne jest, jeśli te 64 bajty zawierają odpowiednie dane, jeśli możemy zmieścić wiele elementów o wartości danych w tych 64 bajtach, i jeśli nasze wzorce dostępu są takie, że wykorzystamy to wszystko przed eksmisją danych.

Te często używane dane dla miliona elementów mogą zajmować jedynie 20 megabajtów, mimo że mamy gigabajty. Nadal robi różnicę w liczbie klatek na sekundę zapętlającą się wokół tych danych, co każdą narysowaną klatkę, jeśli pamięć jest szczelna i blisko siebie, aby zminimalizować straty pamięci podręcznej, i tam właśnie zarządzanie / kontrola pamięci jest tak przydatna. Prosty przykład wizualny na kuli z kilkoma milionami wierzchołków:

wprowadź opis zdjęcia tutaj

Powyższe jest w rzeczywistości wolniejsze niż moja zmienna wersja, ponieważ testuje trwałą reprezentację struktury danych siatki, ale z tym bokiem starałem się osiągnąć takie szybkości klatek nawet przy połowie tych danych (co prawda sprzęt był szybszy od moich zmagań ), ponieważ nie rozumiem, jak minimalizować błędy pamięci podręcznej i zużycie pamięci dla danych siatki. Siatki to jedne z najtrudniejszych struktur danych, z którymi miałem do czynienia w tym względzie, ponieważ przechowują tak wiele współzależnych danych, że muszą być zsynchronizowane, takie jak wielokąty, krawędzie, wierzchołki, tyle map tekstur, ile użytkownik chce dołączyć, masy kości, mapy kolorów, zestawy wyboru, cele przekształcenia, grubości krawędzi, materiały wielokątów itp. itd. itd.

W ciągu ostatnich kilku dekad zaprojektowałem i wdrożyłem wiele systemów siatkowych, a ich prędkość była często bardzo proporcjonalna do wykorzystania pamięci. Mimo że pracuję z tym, o wiele więcej pamięci niż na początku, moje nowe systemy siatki są ponad 10 razy szybsze niż mój pierwszy projekt (prawie 20 lat temu) i w dużym stopniu, ponieważ zużywają około 1/10 pamięć. Najnowsza wersja wykorzystuje nawet indeksowaną kompresję do wtłoczenia jak największej ilości danych, i pomimo narzutu związanego z przetwarzaniem dekompresji, kompresja faktycznie poprawiła wydajność, ponieważ znowu mamy tak mało cennej szybkiej pamięci. Mogę teraz dopasować milion siatki wielokątów ze współrzędnymi tekstury, bigowaniem krawędzi, przypisaniami materiałów itp. Wraz z indeksem przestrzennym dla tego w około 30 megabajtach.

Oto modyfikowalny prototyp z ponad 8 milionami czworokątów i wielozadaniowym schematem podziału na i3 z GF 8400 (to było kilka lat temu). Jest szybszy niż moja niezmienna wersja, ale nie jest używana w produkcji, ponieważ uważam, że wersja niezmienna jest o wiele łatwiejsza w utrzymaniu, a wydajność nie jest taka zła. Zauważ, że szkielet nie wskazuje faset, ale łatki (druty są w rzeczywistości krzywymi, w przeciwnym razie cała siatka byłaby jednolita czarna), chociaż wszystkie punkty w elemencie są modyfikowane przez pędzel.

wprowadź opis zdjęcia tutaj

Tak czy inaczej, chciałem tylko pokazać niektóre z powyższych powyżej, aby pokazać konkretne przykłady i obszary, w których zarządzanie pamięcią jest tak pomocne, a także mam nadzieję, że ludzie nie myślą, że po prostu mówię poza moim tyłkiem. Często denerwuję się, gdy ludzie mówią, że pamięć jest tak obfita i tania, ponieważ chodzi o wolną pamięć, taką jak DRAM i dyski twarde. Jest wciąż tak mały i tak cenny, gdy mówimy o szybkiej pamięci, a wydajność dla naprawdę krytycznych (tj. Często spotykanych przypadków, nie dla wszystkiego) ścieżek odnosi się do grania z tak małą ilością szybkiej pamięci i wykorzystywania jej tak skutecznie, jak to możliwe .

W przypadku tego rodzaju rzeczy bardzo pomocna jest praca z językiem, który pozwala na przykład projektować obiekty wysokiego poziomu, takie jak C ++, jednocześnie zachowując te obiekty w jednej lub kilku sąsiadujących tablicach z gwarancją, że pamięć wszystkie takie obiekty będą reprezentowane w sposób ciągły i bez niepotrzebnego narzutu pamięci na obiekt (np. nie wszystkie obiekty wymagają refleksji lub wirtualnej wysyłki). Kiedy faktycznie przenosisz się do obszarów krytycznych pod względem wydajności, staje się to wzrostem wydajności, aby mieć taką kontrolę nad pamięcią, powiedzmy, majstrowanie przy pulach obiektów i używanie prymitywnych typów danych, aby uniknąć narzutu obiektu, kosztów GC i aby często uzyskiwać dostęp do pamięci razem przylegające.

Tak więc zarządzanie pamięcią / kontrola (lub jej brak) jest w moim przypadku dominującym powodem wyboru języka, który najbardziej produktywnie pozwala mi rozwiązywać problemy. Zdecydowanie piszę swoją część kodu, który nie jest krytyczny pod względem wydajności, i do tego zwykle używam Lua, którą dość łatwo można osadzić w C.


źródło