Memory Mapped IO

  • Memory Mapped IO işlemleriyle temel olarak, read, write fonksiyonlarıyla yapılacak bir IO operasyonunun, ilgili sürecin adreslediği bellek alanı içerisinde doğrudan bellek erişim yöntemleriyle gerçeklenmesini sağlar.

  • Birden fazla süreç, bir dosyayı kendi bellek alanlarına bu şekilde adreslediklerinde, aynı dosya üzerinde aynı anda bellek operasyonlarıyla işlem yapabilirler.

  • Eğer mapping işlemi, MAP_PRIVATE bayrağı ile oluşturulmuş ise, ilgili sürecin yaptığı değişiklikleri diğer süreçler göremezler. Bu şekildeki bir kullanım aynı zamanda, yapılan değişikliklerin dosyaya da tekrar yazılmayacağı anlamına gelmektedir.

  • MAP_SHARED bayrağı ile oluşturulmuş mapping'lerde ise, diğer süreçler de yapılan değişiklikleri görebilirler. Bu değişiklikler işletim sistemi tarafından dosyaya da yansıtılır.

mmap

    #include <sys/mman.h>
    void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
  • mmap sistem çağrısı ile ilgili sürecin adresleme aralığında yeni bir mapping oluşturulur.

  • addr alanı NULL ise sistem tarafından uygun bir adres otomatik olarak atanır.

  • İşlemin başarılı olması durumunda, ilgili bellek adresi geri dönülür, diğer durumda MAP_FAILED makrosuyla test edebileceğimiz bir değer döner.

  • length değeri mapping yapmak istediğimiz uzunluğu gösterir.

  • prot değeri ilgili alan üzerindeki erişim yetkilerini gösterir.

  • PROT_NONE: ilgili alana erişim engellenir

  • PROT_READ: okunabilir

  • PROT_WRITE: yazılabilir

  • PROT_EXEC: kod çalıştırılabilir

  • Bu değerler veya operatörüyle birleştirilebilir.

  • flags parametresi ile alanın kullanım şeklinde dair opsiyonlar belirtilir.

  • MAP_PRIVATE olması durumunda, yapılan değişiklikler sadece mapping'i yapan süreç içerisinde görünebilir. Sistem bu noktada copy-on-write mekanizmasını kullanır ve değişiklik yapılmadığı müddetçe ek bir bellek kaybı söz konusu olmaz.

  • MAP_SHARED olması durumunda, yapılan değişiklikler aynı mapping işlemini yapmış diğer süreçlerde de görünür. Aynı zamanda sistem tarafından dosyaya da yansıtılır. Burada dosyaya yazma işlemini garanti etmek amacıyla msync sistem çağrısı da kullanılabilir.

Örnek: mmap kullanımı

#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "../common/debug.h"

int main(int argc, char *argv[])
{
        char *addr;
        int fd;
        struct stat sb;
        if (argc != 2 || strcmp(argv[1], "--help") == 0)
                usageErr("%s file\n", argv[0]);
        fd = open(argv[1], O_RDONLY);
        if (fd == -1)
                errExit("open");

        /*  Obtain the size of the file and use it to specify the size of
         *  the mapping and the size of the buffer to be written */
        if (fstat(fd, &sb) == -1)
           errExit("fstat");

        addr = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
        if (addr == MAP_FAILED)
                errExit("mmap");

        if (write(STDOUT_FILENO, addr, sb.st_size) != sb.st_size)
                fatal("partial/failed write");

        exit(EXIT_SUCCESS);
}

munmap

  • mmap işleminin tersini yaparak ilgili sürecin bellek alanındaki mapping'i kaldırır.

  • Bellek üzerinde yapılan operasyonların dosya üzerinde de gerçekleştiğinden emin olmak için, munmap öncesinde msync fonksiyonunu kullanmak gerekir.

Dosya Mapping İşlemleri

  • MAP_PRIVATE yöntemiyle dosyalar üzerinde mapping uygulamak, özellikle çalıştırılabilir dosyalar ve paylaşımlı kütüphane kullanımı için önemlidir.

  • Bu sayede aynı uygulamanın veya kütüphanenin text segmenti salt-okunur olarak açılabilir ve sistemdeki tüm süreçler tarafından ortak kullanılabilirken, data segmenti her süreç için özel olarak mapping yapıldığından, ilgili sürece ait değişiklikleri taşıyabilir.

  • MAP_SHARED yöntemiyle uygulanan mapping işlemlerinde ise tüm süreçler bellekteki aynı fiziksel alanı kullandığından önemli bir performans kazancı oluşur.

Memory Mapped IO Avantajları

  • read, write operasyonlarına yerine bellek üzerinde işlem yapmak, daha kolay okunur ve kısa kodlar üretebilmemizi sağlar.

  • Tanımlanmış bir struct ile, bellek üzerinde geziniyormuş gibi işlemler yapılabilir. Özellikle rastgele erişimli dosyalarda ciddi bir kolaylık sağlanır.

  • Bu yöntemle yapılan operasyonlar daha performanslı çalışır.

  • Normal read ve write işlemlerinde, sistemde 2 adet transfer işlemi oluşur. Bunlardan birincisi verinin dosyadan kernel içerisindeki tampon alanına taşınması, ikincisi ise tampon alandan ilgili userspace sürecin bellek alanına taşınması işlemidir.

  • Memory mapped IO modelinde ikinci işleme gerek olmadığından, hem taşıma işleminden kurtulunur, hem de toplamda ihtiyaç duyulan bellek miktarı azalır. Özellikle birden fazla sürecin aynı (büyük) dosya üzerinde rastgele erişim yaptığı modelde önemli oranda avantaj sağlamaktadır.

Dezavantajlar

  • Küçük çaplı IO işlemlerinde, memory mapped IO yönteminin performansı daha düşük olacaktır.

  • Bunun temel nedeni, başlangıçta gereken ekstra mapping işlemi, page fault, unmap işlemleri vb.)

  • Bir diğer problem de bellek üzerinde yapılan işlemlerin dosyaya yansıtılmasını garanti etmek için ek işlem yapılma ihtiyacı olarak gösterilebilir.

  • Bu nedenlerle basit dosya işlemlerinde kullanımı genellikle önerilmez.

results matching ""

    No results matching ""