SORU
22 NİSAN 2010, PERŞEMBE


Neden malloc calloc memset daha yavaştır?

Bellek tahsis başlatır o calloc malloc daha farklı olduğu biliniyor. calloc ile bellek sıfır olarak ayarlanır. malloc ile bellek temizlenmez.

Günlük çalışma, 10* memset* callocgörüyorum. Bu arada, eğlenmek için, bir karşılaştırma için aşağıdaki kodu yazdım.

Sonuç kafa karıştırıcı.

Kod 1:

#include<stdio.h>
#include<stdlib.h>
#define BLOCK_SIZE 1024*1024*256
int main()
{
        int i=0;
        char *buf[10];
        while(i<10)
        {
                buf[i] = (char*)calloc(1,BLOCK_SIZE);
                i  ;
        }
}

Kod 1 çıkış:

time ./a.out  
**real 0m0.287s**  
user 0m0.095s  
sys 0m0.192s  

Kod 2:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define BLOCK_SIZE 1024*1024*256
int main()
{
        int i=0;
        char *buf[10];
        while(i<10)
        {
                buf[i] = (char*)malloc(BLOCK_SIZE);
                memset(buf[i],'\0',BLOCK_SIZE);
                i  ;
        }
}

Kod çıktısı 2:

time ./a.out   
**real 0m2.693s**  
user 0m0.973s  
sys 0m1.721s  

Kod 2 bzero(buf[i],BLOCK_SIZE) memset yerine aynı sonucu verir.

Benim sorum:Neden 18* memset *çok calloc daha yavaştır? Nasıl calloc bunu yapabilir mi?

CEVAP
22 NİSAN 2010, PERŞEMBE


Bu muhtemelen büyük ayırma boyutu nedeniyle. Nasıl sanal bellek çalışır ve OS teorisi üzerinde okumak isteyebilirsiniz.

Zaman ayırmak yeterli büyüklükte bir bölgenin bellek (eşik genellikle 1 MiB eğer yanlış hatırlamıyorsam), en yöneticileri olacak yeni bir bölge bellekten çekirdek kullanarak "yüksek" sadece bu bölge. "Yüksek" hafıza, yeni bir sayfa verir . ancak, ^em>varsıfır MAP_ANONYMOUS kullanırken) başlatılması için. Eğer diğer uygulamalardan önemsiz her türlü ile dolu olurdu, öyle olmasaydı, — ve bu ciddi bir güvenlik açığı. Eğer kök bu sayfaları /etc/shadow düzenleme olsaydı? Aynı "malloc" küçük bir tahsisat bellek çalışır ve "daha fazla. almak için sbrk ararsa da geçerlidir

Ama çok uzun hepsini hafıza sıfır alırdı. Çekirdek Hileleri. Bellek sayfası zaten bir kenara sıfırlanmış. Tüm arasında paylaşılmış olan fiziksel ram, Bu sayfada yeni ayırma noktasında tüm sayfaları sistem süreçleri, aslında herhangi bir bellek kullanımı yok. Salt okunur olarak işaretlenmiş. Siz yazar yazmaz, işlemci bir özel durum oluşturur. Çekirdek özel durum işleyicisi sonra RAM bir sayfaya (muhtemelen başka bir şey dışarı takas) kapmak, sıfır ile doldurur, ve işlemin Adres içine alan haritalar. "" Bu işlev gösteremez. calloc

(Aslında, çekirdek bir adım daha ileri gidebilir ve"". yüksek olması ^em>hiçbir şeyişleminize ait okuyana kadar bellek.)

"Memset çekirdek o sayfaları şimdi, aslında onları kullanmak kadar beklemek yerine ayırmaya güçleri" uygulaması dokunur tahsisinde her sayfa, çok daha yüksek bellek kullanımı sonucu.

"Calloc" uygulama sadece birkaç sayfa tabloları değişiklikler, çok az gerçek bellek tüketir, çok az bellek yazar ve verir. Çoğu sistemde bile sistem (RAM takas daha sorunsuz, tüm yazmıyorsun sürece destek çok daha fazla bellek ayırabilirsiniz. (Bu özellik bu izin işletim sistemlerinde biraz tartışmalı.)

Bazı sistemler sanal bellek desteklemez: çok eski olanlar (80286 sanırım) ve Bazı gömülü sistemler. Bu sistemlerde, hızları çok daha yakın olabilir.


"Memset" "" "memset" bellek hizalanır kabul edemez. çünkü calloc daha yavaş olduğu varsayımında diğer cevaplar içinde birkaç tahminim var Burada tipik bir "" uygulama çalışmaları: . memset nasıl

function memset(dest, c, len)
    // one byte at a time, until the dest is aligned...
    while (len > 0 && ((unsigned int)dest & 15))
        *dest   = c
        len -= 1
    // now write big chunks at a time (processor-specific)...
    // block size might not be 16, it's just pseudocode
    while (len >= 16)
        // some optimized vector code goes here
        // glibc uses SSE2 when available
        dest  = 16
        len -= 16
    // the end is not aligned, so one byte at a time
    while (len > 0)
        *dest   = c
        len -= 1

256 MiB bir parça, ilk ve son döngü önemsiz olacak, ve orta döngü varsayımsal calloc döngü aynıdır. Bazı Derleyiciler içi "" ve sonuç "malloc" uyumlu bir ilişki vardır. ulaşabilirse memset Ve tipik bir "uygulama sadece" "her neyse —" genellikle C ile yazılmış, ve sık sık işletim sistemleri arasında taşınabilir. "calloc memset aramalar" calloc

Diğer "malloc "memset" iki kere başlatır. bu yüzden" zaten hafıza başlatır, bunu gördüm sanırım Buteknik olarakgerçek bu durumda. Ancak, sadece hız iki kat hakkında bu yüzden olmuş olabilir. "On sürüm için." calloc ^em>bin beş yüzkat daha hızlı. Sayıları sonuç desteklemez.


Dipnot:Espri olsun diye, benim bilgisayar ikide iki program yapamazsın. OS X Power PC kutudan, memset sürümü 1500x yavaş (8 s karşı 5 ms) sona erdi. / 86 benim Linux kutusu üzerinde, memset sürümü 35x için uzun segfaulting önce (beklenen, bu bilgisayar az RAM — not olsa o calloc sürümüyoktucrash).

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Le Cargo !

    Le Cargo !

    24 HAZİRAN 2007
  • Missouri Star Quilt Company

    Missouri Sta

    18 ŞUBAT 2009
  • SegaAmerica

    SegaAmerica

    5 Mart 2008