Sabit zamanlı işlemlerle akıllı bellek yönetimi?


18

Sabit boyutlu blokları içeren iki temel bellek ayırma işlemi gerçekleştirebileceğiniz bir bellek segmentini (gerektiğinde dosya gibi büyüyebilen veya küçülebilen bir bellek segmenti) düşünelim:

  • bir blok tahsisi
  • artık kullanılmayan önceden tahsis edilmiş bir bloğun serbest bırakılması.

Ayrıca, bir gereksinim olarak, bellek yönetim sisteminin şu anda tahsis edilmiş bloklar etrafında hareket etmesine izin verilmez: dizin / adresleri değişmeden kalmalıdır.

En saf bellek yönetimi algoritması genel bir sayacı (başlangıç ​​değeri 0 olan) artırır ve yeni değerini bir sonraki ayırma için adres olarak kullanır. Ancak bu, yalnızca birkaç tahsis edilmiş blok kaldığında segmenti kısaltmaya asla izin vermeyecektir.

Daha iyi yaklaşım: Sayacı koruyun, ancak yeniden ayrılmış blokların bir listesini tutun (bu, sabit zamanda yapılabilir) ve boş olmadığı sürece yeni tahsisler için bir kaynak olarak kullanın.

Sırada ne var? Hafıza segmentini olabildiğince kısa tutacak sabit zaman tahsisi ve dağıtma kısıtlamaları ile yapılabilecek zekice bir şey var mı?

(Şu anda tahsis edilmemiş bloğu en küçük adresle izlemek olabilir, ancak sabit zamanda mümkün görünmüyor…)


daha önce yapılan bazı tahsisler / dislokasyonlar nedeniyle liste büyüyebileceği veya küçülebileceği için bir listenin kontrolü artık sabit zamanlı olmaz mı?
Sim

@Sim, bunun bağlantılı bir liste olduğunu varsayıyordum ve onunla işlemler olurdu , çünkü her zaman sadece kafa ile çalışıyorsunuz. O(N)
svick

Bence “daha ​​iyi yaklaşımınız” zaten optimum miktarda bellek kullanacaktır, yani boş bir blok varsa asla ek bellek ayırmayacaktır. “Akıllı” yaklaşımın bu konuda gelişeceğini nasıl düşünüyorsunuz? Diyelim ki, yeniden konumlandırmadan sonra segmenti küçültme şansınız daha yüksek olacak şekilde, başlangıca yakın tahsis etmeli mi?
svick

@Sim: Üzgünüm, belki yığın terimini kullanmalıydım (ama kafa karıştırıcı olabileceğini düşündüm), 'deallocate' itme ve 'tahsis etme' pop ya da başarısız olursa sayaç artmasına geri dönüyor. Her ikisi de sabit zamandır.
Stéphane Gimenez

Gerçek zamanlı kısıtlamalarınız var mı veya itfa edilmiş sabit zaman konusunda iyi misiniz? Cevapların oldukça farklı olması muhtemeldir.
Gilles 'SO- kötü olmayı bırak'

Yanıtlar:


11

Sabit boyutlu bloklarda, tanımladığınız şey ücretsiz bir listedir . Bu, aşağıdaki bükülme ile çok yaygın bir tekniktir: serbest blokların listesi serbest blokların kendisinde saklanır. C kodunda şöyle görünecektir:

static void *alloc_ptr = START_OF_BIG_SEGMENT;
static void *free_list_head = NULL;

static void *
allocate(void)
{
    void *x;

    if (free_list_head == NULL) {
        x = alloc_ptr;
        alloc_ptr = (char *)alloc_ptr + SIZE_OF_BLOCK;
    } else {
        x = free_list_head;
        free_list_head = *(void **)free_list_head;
    }
    return x;
}

static void
release(void *x)
{
    *(void **)x = free_list_head;
    free_list_head = x;
}

Bu, tahsis edilen tüm bloklar aynı boyuta sahip olduğu ve bu boyutun bir işaretçinin boyutunun katı olduğu sürece iyi çalışır, böylece hizalama korunur. Ayırma ve yeniden yerleştirme sabit sürelidir (yani, bellek erişimi ve temel eklemeler gibi sabit süredir - modern bir bilgisayarda, bellek erişimi önbellek özümlerini ve hatta sanal belleği içerebilir, dolayısıyla disk erişimlerini içerebilir, böylece "sabit zaman" oldukça büyük olabilir). Bellek yükü yoktur (blok başına fazladan işaretçi veya bunun gibi şeyler yoktur; tahsis edilen bloklar bitişiktir). Ayrıca, ayırma işaretçisi yalnızca bir kerede birçok bloğun atanması gerektiğinde belirli bir noktaya ulaşır: ayırma serbest listeyi kullanmayı tercih ettiğinden, ayırma işaretçisi yalnızca geçerli işaretçinin altındaki boşluk saat dolu olduğunda artar. Bu anlamda, tekniği.

azalanserbest bırakma işleminden sonra ayırma işaretçisi daha karmaşık olabilir, çünkü serbest bloklar, yalnızca öngörülemeyen sırayla geçen serbest liste izlenerek güvenilir bir şekilde tanımlanabilir. Mümkün olduğunda büyük segment boyutunu azaltmak sizin için önemliyse, daha fazla yük ile alternatif bir teknik kullanmak isteyebilirsiniz: tahsis edilen iki blok arasına bir "delik" koyarsınız. Delikler, bellek düzeninde çift bağlantılı bir listeyle birbirine bağlanır. Bir delik için, nerede bittiğini bilerek delik başlangıç ​​adresini ve deliğin bellekte nerede başladığını biliyorsanız delik boyutunu bulabileceğiniz bir veri formatına ihtiyacınız vardır. Daha sonra, bir bloğu serbest bıraktığınızda, sonraki ve önceki deliklerle birleştirdiğiniz, tüm deliklerin sıralı listesini (yine sabit zamanda) yeniden oluşturduğunuz bir delik oluşturursunuz. Tepegöz daha sonra tahsis edilen blok başına yaklaşık iki işaretçi boyutunda sözcüktür; ancak bu fiyatta, bir "son delik" oluşumunu, yani büyük segment boyutunu azaltma vesilesiyle güvenilir bir şekilde tespit edebilirsiniz.

Birçok olası varyasyon vardır. İyi bir giriş belgesi Dinamik Depolama Tahsisi: Wilson ve ark.


4
Bir anlaşma bölgesine en yakın delikleri sabit zamanda nasıl bulursunuz?
Raphael

1
Açıkladığım ikinci yöntemde bir delik, sıfır, bir veya daha fazla veri bloğu için alanla birlikte bir başlıktır (delik listesi için bir çift işaretçi). Tahsis edilen herhangi iki blok arasında , sadece bir delik başlığından oluşan bir mikro delik olsa bile , her zaman bir delik vardır . Bu yüzden en yakın delikleri bulmak kolaydır: yuvadan hemen önce ve hemen sonradırlar. Tabii ki, mikro delikler serbest listenin bir parçası değildir (tahsis için uygun deliklerin listesi). Bunu izlemenin başka bir yolu, her bloğa ve her (mikro olmayan) deliğe bir başlık eklemenizdir (16 bit Ms-Dos altında ayırma böyle çalıştı).
Thomas Pornin

4

Bu cevap genel bellek yönetimi teknikleri ile ilgilidir. Sorunun, tüm blokların aynı boyuta (ve hizalanmış) sahip olduğu durumu sorduğunu kaçırdım.


Bilmeniz gereken temel stratejiler, ilk, sonraki, en uygun ve arkadaş sistemidir . Öğrettiğim bir kurs için bir kez kısa bir özet yazdım , umarım okunabilir. Orada oldukça kapsamlı bir ankete işaret ediyorum .

Uygulamada bu temel stratejilerin çeşitli değişikliklerini göreceksiniz. Ama bunların hiçbiri gerçekten sabit bir zaman değil! Sınırlı miktarda bellek kullanırken bunun en kötü durumda mümkün olduğunu düşünmüyorum.


İlginç, bunu ayrıntılı olarak okumak zorundayım. Ancak, bu sistemlerin özellikle sabit olmayan boyut ayırmalarıyla uğraştığı görülüyor, bu da karşı karşıya olduğum bir sorun değil.
Stéphane Gimenez

Sağ. Üzgünüm, sorunuzu çok hızlı okudum.
rgrig

O(lgn)

s / en küçük serbest blok / en küçük adresten ücretsiz blok /
rgrig

2

İtfa edilmiş analizlere ve özellikle dinamik dizilere göz atmak isteyebilirsiniz . Operasyonlar her adımda sabit zamanda gerçekten yapılmasa bile, uzun vadede durum böyle görünüyor.


2
Dinamik diziler bellek ayırmada tam olarak nasıl yardımcı olacak?
svick

Aynı tür algoritmayı kullanarak bitişik hücre parçalarını tahsis eder misiniz? Dosyanızın tamamı, daha büyük ve daha büyük parçaların bağlantılı bir listesi olacaktır.
gallais
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.