2012-12-19 9 views
8

w Linuksie, gdy proces prosi o (wirtualny) pamięci z systemu, to po prostu zarejestrowany w VMA (deskryptor wirtualnej pamięci procesu jest), ale strony fizycznej dla każdego wirtualnego nie jest zarezerwowana w czas połączenia. Później, kiedy proces uzyska dostęp do tej strony, zostanie ona zarzucona (dostęp wygeneruje przerwanie Page Fault), a program obsługi PF # przydzieli fizyczną stronę i aktualizuje tabelę stron procesu.stos prefaulting w linux - pojedyncze lub wielokrotne awarie wymagające

Istnieją dwa przypadki: błąd przy czytaniu może przekształcić się odnośnik do strony zerowej (specjalny globalny wstępnie wyzerowany strony), która jest zabezpieczona przed zapisem; i błąd w zapisie (zarówno na stronie zerowej, jak i na wymaganej, ale nie fizycznej stronie) spowoduje fizyczną fizyczną alokację strony.

Na mmaps (i BRK/sbrk, która jest wewnętrznie mmap zbyt) metoda ta jest na stronie; wszystkie obszary mmone są zarejestrowane jako całość w vma (mają adresy początkowy i końcowy). Ale stos jest obsługiwany w inny sposób, ponieważ ma tylko adres początkowy (wyższy na typowej platformie, rośnie na niższe adresy).

Pytanie brzmi:

Kiedy dostępu nowej nieprzydzielone pamięci pobliżu stosu, to dostać PF # i rosnąć. Jak to rośnie, jeśli mam dostęp do strony obok stosu, ale strona, która jest 10 lub 100 stron z dala od stosu?

E.g.

int main() { 
    int *a = alloca(100); /* some useful data */ 
    int *b = alloca(50*4096); /* skip 49 pages */ 
    int *c = alloca(100); 

    a[0]=1; 
/* no accesses to b - this is untouched hole of 49 pages */ 
    c[0]=1; 

} 

Czy ten program otrzyma 2 lub 50 prywatnych stron fizycznych przydzielonych do stosu?

Myślę, że może być opłacalne zapytać jądra przeznaczyć dziesiątki fizycznych stron w pojedynczym pagefault następnie zrobić kilkadziesiąt pagefaults przydzielanie strona po stronie (1 przerwania + 1 kontekstowego-switch + proste, cache przyjazne pętli nad N żądań strona alokacji versus N przerwań + N przełączników kontekstowych + alokacji stron N, kiedy kod mm może zostać wyeksmitowany z Icache).

+0

Dzięki za interesujące pytanie. (+1) – NPE

Odpowiedz

2

Automatyczny uprawa stosie mogą być traktowane jako automatycznych połączeń do mremap, aby zmienić rozmiar regionu adresów wirtualnych, który jest liczony jako "stos". Po tym, jak to się dzieje, błędy stron do obszaru stosu lub do obszaru mmap wanilii są traktowane tak samo, tj. Po jednej stronie na raz.

Zatem należy skończyć z około 2 stron przeznaczonych, nie ~ 51. @ empiryczna odpowiedź @ perreal potwierdza to ...

Do końca części pytania, koszt ciągłych błędów stron jest jednym z czynników, które prowadzą do rozwoju "ogromnych stron". Nie sądzę, że w Linuksie istnieją inne sposoby "porcjowania" obsługi błędów strony. Być może madvise może coś zrobić, ale podejrzewam, że głównie optymalizuje naprawdę kosztowną część błędów stron, które szukają kopii zapasowych stron w pamięci). Błędy stosu stron, które odwzorowują na zero stron, są względnie lekkie w porównaniu.

+0

i 'MLOCK (2)' będzie prefault też. – osgx

4

Z tym kodem:

int main() { 
    int *a = alloca(100); /* some useful data */ 
    int *b = alloca(50*4096); /* skip 49 pages */ 
    int *c = alloca(100); 
    int i; 
#if TOUCH > 0 
    a[0] = 1;    // [1] 
#endif 
#if TOUCH > 1 
    c[0] = 1;    // [2] 
#endif 
#if TOUCH > 2 
    for (i=0; i<25; i++) // [3] 
    b[i*1024] = 1; 
#endif 
#if TOUCH > 3 
    for (i=25; i<50; i++) // [4] 
    b[i*1024] = 1; 
#endif 
    return 0; 
} 

a ten skrypt:

for i in 1 2 3 4; do 
    gcc d.c -DTOUCH=$i 
    echo "Upto [$i]" $(perf stat ./a.out 2>&1 | grep page-faults) 
done 

Wyjście:

Upto [1] 105 page-faults # 0.410 M/sec 
Upto [2] 106 page-faults # 0.246 M/sec 
Upto [3] 130 page-faults # 0.279 M/sec 
Upto [4] 154 page-faults # 0.290 M/sec 
+0

Więc, około 104 stron-usterek dla kodu programu i jego bibliotek .. – osgx