Programlamada bellek yönetimi alakasız bir mesele haline mi geliyor?
Bellek yönetimi (veya kontrolü) aslında C ve C ++ kullanmamın ana nedeni.
Bellek şimdi nispeten ucuz.
Hızlı hafıza değil. Halen i7'deki L1 için 32KB, L2 için 256KB ve L3 / core için 2MB gibi bir miktar veri kaydına bakıyoruz. Bahsedilen:
Eğer çalışma hafızasında (yani gömülü sistemler ve benzeri) katı sınırlara sahip hedef platformlar açısından konuşmazsak, bugün genel amaçlı bir dil seçerken bellek kullanımı kaygı verici mi olmalı?
Genel seviyede hafıza kullanımı, belki de değil. Biraz pratik değil, çünkü 50 megabayt DRAM ve yüzlerce megabayt sabit disk alanı kaplayan bir not defteri fikrinden hoşlanmıyorum. Uzun zamandır buralardayım ve bu kadar basit bir uygulamanın kilobayt ile ne yapılması gerektiğine dair oldukça fazla bellek harcadığını görmek bana biraz tuhaf geliyor. Bununla birlikte, eğer hala iyi ve duyarlı olsaydı, böyle bir şeyle karşılaştıysam kendimle yaşayabileceğimi söyledi.
Alanımda bellek yönetiminin benim için önemli olmasının nedeni, bellek kullanımını genel olarak çok fazla azaltmak değil. Yüzlerce megabayt bellek kullanımı, bu belleğe sık sık erişilmiyorsa, bir uygulamayı önemsiz olmayan bir şekilde yavaşlatmayacaktır (örneğin: yalnızca bir düğmeyi tıklattığınızda veya başka bir kullanıcı girişi biçiminde, bu durum sizler oldukça seyrek görülür) Saniyede milyon kere bir düğmeye basabilecek Koreli Starcraft oyuncularından bahsediyoruz).
Alanımda önemli olmasının nedeni , bu kritik yollarda çok sık erişilen (örneğin: her kareye ilmekli) belleğin sıkı ve birbirine yakın hale gelmesidir. Her karede bir döngüde erişilmesi gereken milyon öğeden sadece birine eriştiğimizde, önbellek kaçırmak istemiyoruz. 64 parça bayt önbellek satırını, büyük parçalarda hafızayı yavaş bellekten hızlı belleğe taşıdığımızda, 64 bayt önbellek satırları söz konusu olduğunda, bu 64 baytın hepsinde alakalı veriler içeriyorsa, bu 64 bayta veri değerinde birden fazla öğeye sığabilirsek ve Erişim kalıplarımız, veriler çıkarılmadan önce hepsini kullanırız.
Milyonlarca element için sıkça erişilen veriler, gigabaytlarımız olmasına rağmen sadece 20 megabaytlık bir alanı kapsayabilir. Hafıza, önbellek kayıplarını en aza indirmek için birbirine yakın ve yakın olması durumunda çizilen her bir karede, bu veriler üzerinden geçen kare hızlarında bir fark yaratıyor. Birkaç milyon köşeli bir alanda basit görsel örnek:
Yukarıdakiler aslında benim değişken sürümümden daha yavaştır, çünkü bir ağın kalıcı bir veri yapısı gösterimini test eder, ancak bir yana, bu verilerin yarısında bile bu kare hızlarını elde etmek için mücadele ederdim (kuşkusuz donanım mücadelelerimden bu yana daha hızlı oldu. ) çünkü önbellek eksikliklerini ve ağ verileri için bellek kullanımını en aza indirmeyi alamadım. Ağlar, bu konuda ele aldığım en zorlu veri yapılarından bazılarıdır, çünkü çokgenler, kenarlar, köşeler, kullanıcının eklemek istediği kadar doku haritası, kemik ağırlıkları gibi senkronize kalmak zorunda olan çok fazla bağımlı veri depolarlar. renk haritaları, seçim setleri, morph hedefleri, kenar ağırlıkları, poligon malzemeleri vb.
Geçtiğimiz birkaç on yılda bir dizi ağ sistemi tasarladım ve uyguladım ve hızları hafıza kullanımları ile çok orantılıydı. Çalıştığımdan çok daha fazla bellek ile çalışsam da, yeni örgü sistemlerim ilk tasarımımdan (neredeyse 20 yıl önce) 10 kat daha hızlı ve büyük ölçüde de 10 / 10'u kullanıyor çünkü Hafıza En yeni sürüm mümkün olduğu kadar çok veriyi toplamak için endekslenmiş sıkıştırma bile kullanıyor ve dekompresyonun üst kısmındaki işleme rağmen, sıkıştırma aslında performansı arttırdı, çünkü yine de çok az değerli hızlı belleğe sahibiz. Şimdi, yaklaşık 30 megabaytlık bir uzay indeksi ile birlikte doku koordinatları, kenar oluşturma, malzeme atamaları vb.
İşte 8 milyondan fazla dörtlü ve G3 8400'lü bir i3'te çok telli bir alt şema içeren değişken prototip (bu birkaç yıl önceydi). Değişmez versiyonumdan daha hızlı, ancak üretimde kullanılmıyor, çünkü değişmez versiyonun bakımını çok daha kolay buldum ve performans vuruşu çok da kötü değil. Tel çerçevenin fasetleri göstermediğini, ancak yamalar (teller aslında eğriler, aksi takdirde tüm ağın tamamı siyah olacaktır), bir fasetteki tüm noktalar fırça tarafından değiştirilse de dikkat edin.
Her neyse, bellek yönetiminin çok yararlı olduğu bazı somut örnekler ve alanlar göstermek için bunlardan bazılarını göstermek istedim ve umarım insanlar da benim popomdan çıktığımı düşünmüyorlar. İnsanlar hafızanın çok ve ucuz olduğunu söylerken biraz sinirlenmeye meyilliyim çünkü bu DRAM ve sabit diskler gibi yavaş hafızadan bahsediyor. Hızlı hafızadan bahsettiğimiz zaman hala çok küçük ve çok kıymetlidir ve gerçekten kritik (yani, her şey için değil) ortak yolların performansı, o küçük miktardaki hızlı hafızaya oynamak ve elimizden geldiğince verimli kullanmakla ilgilidir. .
Bu tür bir şey için, örneğin C ++ gibi yüksek seviyeli nesneler tasarlamanıza izin veren bir dille çalışmak gerçekten yararlı olurken, bu nesneleri bir ya da daha fazla bitişik dizide saklayabilmenizi sağlar. tüm bu nesneler bitişik olarak temsil edilecek ve nesne başına yük gerektirmeyen bellek olmadan (ör: tüm nesnelerin yansıması veya sanal gönderime ihtiyacı yoktur). Performans açısından kritik olan bu alanlara gerçekten girdiğinizde, nesne yükünü önlemek, nesne maliyetlerini önlemek ve sık sık erişilen bellek tutmak için ilkel veri türlerini kullanmak, yani nesne havuzları üzerinde çalışmak ve ilkel veri türlerini kullanmak gibi bir bellek kontrolüne sahip olmak aslında verimlilik artışı olur. birlikte bitişik.
Bu yüzden, bellek yönetimi / kontrolü (ya da eksikliği) aslında benim durumumda, hangi dili en verimli bir şekilde sorunların üstesinden gelmeme izin vereceğimi seçmemdeki baskın sebep. Performans açısından kritik olmayan kod payımı kesinlikle yazıyorum ve bunun için C'den gömülmesi oldukça kolay olan Lua'yı kullanma eğilimindeyim.