0Pricing
C Academy · Ders

Basit Bir Artırmalı Ayırıcı

Belleği doğrusal biçimde dağıtın.

Basit Bir Artırmalı Ayırıcı, CoddyKit'te ücretsiz bir C Academy dersidir. Bu, 4 dersinin 2. dersidir. Aşağıdan dersin tamamını ücretsiz okuyabilir, sonra tarayıcıda yerleşik kod editörü ve 7/24 yapay zeka koçu ile uygulamalı olarak pratik yapabilirsin. Bu, C Academy öğrenme yolunun bir parçasıdır ve ilerlemeniz web ve CoddyKit uygulaması arasında senkronize olur. C Academy kursu toplamda 4 dersten oluşur.

Bump Allocator Fikri

Bump (veya arena) ayırıcı, en basit tasarımdır. Büyük bir arabellek ve tek bir uzaklık değeri tutulur. Her bellek ayırma işlemi yalnızca mevcut uzaklığı döndürür, ardından uzaklığı istenen boyut kadar ileri taşır.

Blok başına üstveri ve arama yoktur. Bellek ayırma temelde tek bir işaretçi toplama işlemidir; bu da onu son derece hızlı yapar.

Statik Destek Arabelleği

Kendi kendine yeten bir örnek için ayırıcıyı OS yığını yerine statik bir diziyle destekliyoruz. sbrk veya mmap olmadan her yerde derlenip çalışır.

Dizi, parçalara ayırabileceğimiz sabit bir bayt havuzu sağlar.

#define POOL_SIZE 1024
static unsigned char pool[POOL_SIZE];
static size_t offset = 0;

Temel bump İşlevi

Bellek ayırma işlemi yeterli alan kalıp kalmadığını kontrol eder, başlangıcı kaydeder, uzaklığı ilerletir ve başlangıç işaretçisini döndürür. İstek havuzun sınırlarını aşacaksa NULL döndürür.

Bu taşma kontrolü, bump allocator'ın sağladığı tek güvenlik önlemidir.

void *bump_alloc(size_t size) {
    if (offset + size > POOL_SIZE)
        return NULL;            /* out of pool */
    void *p = &pool[offset];
    offset += size;
    return p;
}

Çalıştırılabilir Eksiksiz Bir Bump Allocator

İşte tam bir program. Havuzdan iki tam sayı ve kısa bir dizi ayırıp bunları yazdırarak ayırıcının çalıştığını kanıtlar.

Gerçek bir malloc ile karşılaştırıldığında ne kadar az kod gerektiğine dikkat ediniz.

#include <stdio.h>
#include <stddef.h>
#include <string.h>

#define POOL_SIZE 1024
static unsigned char pool[POOL_SIZE];
static size_t offset = 0;

void *bump_alloc(size_t size) {
    if (offset + size > POOL_SIZE) return NULL;
    void *p = &pool[offset];
    offset += size;
    return p;
}

int main(void) {
    int *a = bump_alloc(sizeof(int));
    int *b = bump_alloc(sizeof(int));
    char *s = bump_alloc(6);
    *a = 10; *b = 32;
    strcpy(s, "hi");
    printf("%d %d %s\n", *a, *b, s);
    printf("used = %zu\n", offset);
    return 0;
}

Tek Tek Serbest Bırakma Yoktur

Dezavantajı şudur: bump allocator tek bir bellek ayırma işlemini serbest bırakamaz. Üstveri olmadığından bir bloğun nerede bitip diğerinin nerede başladığını yeniden kullanım için bilemez.

Yalnızca uzaklığı sıfıra ayarlayarak tüm arenayı tek seferde sıfırlayabilirsiniz.

void bump_reset(void) {
    offset = 0;   /* frees everything at once */
}

Sıfırlama Neden Yararlıdır?

Bu ya hep ya hiç modeli aşamalı çalışmalar için idealdir: bir istek veya çerçeve sırasında birçok nesne ayırır, aşama sona erdiğinde arenayı sıfırlarsınız.

Oyun motorları ve derleyiciler arenaları yoğun biçimde kullanır; çünkü sıfırlama O(1) maliyetindedir ve binlerce tekil serbest bırakma işlemini izleme gereğini ortadan kaldırır.

/* Per-frame pattern */
for (int frame = 0; frame < 3; frame++) {
    void *tmp = bump_alloc(128);
    /* ... use tmp this frame ... */
    bump_reset();   /* reclaim instantly */
}

Kalan Alanı İzleme

Ne kadar alan kaldığını kullanıma sunmak faydalıdır. Bu, havuz boyutundan mevcut ofsetin çıkarılmasından ibarettir.

Çağıranlar, daha fazla alan istemeden önce havuzu boşaltıp boşaltmamaya veya büyütüp büyütmemeye karar vermek için bunu kullanabilir.

size_t bump_remaining(void) {
    return POOL_SIZE - offset;
}

Çalıştırılabilir Sıfırlama Gösterimi

Bu program havuzun bir bölümünü doldurur, kullanımı yazdırır, sıfırlar ve ofsetin sıfıra döndüğünü gösterir; böylece alan yeniden kullanılabilir.

#include <stdio.h>
#include <stddef.h>

#define POOL_SIZE 256
static unsigned char pool[POOL_SIZE];
static size_t offset = 0;

void *bump_alloc(size_t s){ if(offset+s>POOL_SIZE) return NULL; void *p=&pool[offset]; offset+=s; return p; }
void bump_reset(void){ offset = 0; }

int main(void) {
    bump_alloc(100);
    printf("after alloc: used=%zu\n", offset);
    bump_reset();
    printf("after reset: used=%zu\n", offset);
    return 0;
}

Bump Allocator'da Hizalama

Ham bayt bayt ilerleme, hizalanmamış işaretçiler döndürebilir. Güvenli olmak için işaretçiyi döndürmeden önce ofseti bir hizalama sınırına yuvarlayın.

Matematiği ileride ayrıntılı olarak ele alacağız; ancak başka türlü dolgu bulunmadığından hizalamanın en önemli olduğu yer bump allocator'dır.

static size_t align_up(size_t n, size_t a) {
    return (n + a - 1) & ~(a - 1);   /* a must be power of 2 */
}

Hizalanmış Bump Allocator

Parçaları birleştirerek her ayırmadan önce ofseti hizalarız. Böylece döndürülen her işaretçinin yaygın tüm türler için uygun olması garanti edilir.

Bunun bedeli, dolgu baytlarının oluşturduğu bir miktar iç parçalanmadır.

#define ALIGN 16
void *bump_aligned(size_t size) {
    offset = align_up(offset, ALIGN);
    if (offset + size > POOL_SIZE) return NULL;
    void *p = &pool[offset];
    offset += size;
    return p;
}

Güçlü Yönler ve Sınırlar

Bump allocator'lar eşsiz bir hızda ve son derece basittir; nesne başına ek yükleri sıfırdır. Nesnelerin aynı yaşam süresini paylaştığı durumlar için idealdirler.

Zayıf yönleri, ince taneli serbest bırakmanın bulunmamasıdır. Yaşam süreleri farklı olduğunda, bir sonraki derste ele alınan serbest liste tasarımına ihtiyaç duyarsınız.

Hızlı Kontrol

Bir bump allocator'ın belleği nasıl geri kazandığını düşünün.

Özet

Bump allocator, bir arabellek içindeki tek bir ofseti ilerleterek bellek dağıtır; böylece ayırma işlemi bir işaretçi ekleme işlemi kadar ucuz olur.

Tek tek serbest bırakma işleminden hız ve basitlik uğruna vazgeçer; belleği yalnızca tamamen sıfırlayarak geri kazanır. Döndürülen işaretçilerin tüm türler için geçerli kalması amacıyla ofseti hizalayın.

Sıkça Sorulan Sorular

“Basit Bir Artırmalı Ayırıcı” dersi ücretsiz mi?

Evet — “Basit Bir Artırmalı Ayırıcı” dersin tüm metni burada web'de ücretsiz olarak okunabilir. Etkileşimli olarak pratik yapmak (yerleşik kod editörü ve 7/24 yapay zeka koçu) ve C Academy kursunun geri kalanını açmak için CoddyKit PRO'ya yükselt. C Academy kursu toplamda 4 dersten oluşur.

“Basit Bir Artırmalı Ayırıcı” dersinde ne öğreneceğim?

Belleği doğrusal biçimde dağıtın. C Academy ile uygulamalı kodu tarayıcıda doğrudan çalıştırarak pratik yaparsın ve 7/24 yapay zeka koçu dersi çalışırken sorularını yanıtlar.

C Academy öğrenmeye başlamak için deneyim gerekli mi?

Önceden deneyim gerekmez. CoddyKit'te C Academy, başlangıçtan ileri seviyeye kadar yapılandırıldığı için buradan başlayabilir veya başından başlayıp kendi hızında ilerleme yapabilirsin. Bu, 4 dersinin 2. dersidir.

“Basit Bir Artırmalı Ayırıcı” dersi ne kadar sürer?

Çoğu CoddyKit dersi yaklaşık 5–10 dakika sürer. Her biri kısa ve etkileşimli olduğu için sabit ilerleme yaparsın ve web ile uygulama arasında tam olarak bıraktığın yerden devam edebilirsin.

Bu C Academy dersinde kod yazıp çalıştırabilir miyim?

Evet. Her C Academy dersi yerleşik bir kod editörü içerir, bu sayede tarayıcıda gerçek kod yazıp çalıştırabilir ve anlık yapay zeka geri bildirimi alırsın — yerel kurulum gerekli değildir.

Bu kursun tüm dersleri

  1. malloc Nasıl Çalışır
  2. Basit Bir Artırmalı Ayırıcı
  3. Boş Listeler ve Yeniden Kullanım
  4. Hizalama ve Bölme
← C Academy Sayfasına Dön