[TAOCP] 2.5 동적인 저장소 할당

Post on 27-Jun-2015

1.385 views 3 download

Transcript of [TAOCP] 2.5 동적인 저장소 할당

[TAOCP] 2.5 동적인 저장소 할당

ohyecloudy http://ohyecloudy.com

아꿈사 http://cafe.naver.com/architect1.cafe 2011.06.04

동적 저장소 할당 알고리즘dynamic storage allocation

커다란 저장소 영역에서

가변 크기 메모리 블록들을 예약하고 해제

예약 최초 적합법

해제 정렬된 목록을 이용한 해제

단짝buddy 시스템 단짝 시스템 예약

단짝 시스템 해제

50 퍼센트 규칙

00000 20000 40000 60000 80000

100000

메모리 맵

예약된 영역

자유 영역

가용 공간의

이러한 분할을

컴퓨터 안에서 어떻게 표현?

장소 SIZE LINK

0 101 632

632 42 1488

… … …

73654 1909 77519

77519 53553 Λ

가용 조각segment들을 함께 연결

마지막 링크 표시

가용 공간의 표현이 주어졌을 때,

크기가 n인 블록을 찾고 예약하는

알고리즘은 무엇인가?

최적 적합법best-fit method

크기가 n보다 크거나 같은 블록 중 가장 작은 블록

목록 전체를 검색 (크기가 같은 블록을 찾기 전까지)

최초 적합법first-fit method

크기가 n보다 크거나 같은 블록 중 최초로 발견된 것 선택

최적 적합법이 짱인가?

이름에 best가 붙었잖아

역사적으로 수년 동안 널리 쓰임

속도가 느리고 매우 작은 블록들 개수가 늘어남

메모리 요청 가용 공간(최초 적합) 가용 공간(최적 적합)

1300, 1200 1300, 1200

1000 300, 1200 1300, 200

1100 300, 100 200, 200

250 50, 100 실패

최초 적합법을 우선 선택하는 게 낫다.

두 방법 중

어느 것이 확실히 더 뛰어나지 않다.

그러니 걍 빠르고 더 단순한 걸 쓰자.

예약 최초 적합법

해제 정렬된 목록을 이용한 해제

단짝buddy 시스템 단짝 시스템 예약

단짝 시스템 해제

50 퍼센트 규칙

A1.[초기화] Q ← LOC(AVAIL)

A2.[목록의 끝?] P ← LINK(Q) if (P == Λ) {FAIL!}

A3.[SIZE가 충분한가?] if (SIZE(P)≥N) {goto A4} else { Q ← P, goto A2 }

A4.[N만큼 예약] K ← SIZE(P) – N if (K == 0) {LINK(Q) ← LINK(P)} else {SIZE(P) ← K}

A1.[초기화] Q ← LOC(AVAIL)

A2.[목록의 끝?] P ← LINK(Q) if (P == Λ) {FAIL!}

A3.[SIZE가 충분한가?] if (SIZE(P)≥N) {goto A4} else { Q ← P, goto A2 }

A4.[N만큼 예약] K ← SIZE(P) – N if (K == 0) {LINK(Q) ← LINK(P)} else {SIZE(P) ← K}

AVAIL

Q

A1.[초기화] Q ← LOC(AVAIL)

A2.[목록의 끝?] P ← LINK(Q) if (P == Λ) {FAIL!}

A3.[SIZE가 충분한가?] if (SIZE(P)≥N) {goto A4} else { Q ← P, goto A2 }

A4.[N만큼 예약] K ← SIZE(P) – N if (K == 0) {LINK(Q) ← LINK(P)} else {SIZE(P) ← K}

AVAIL

Q

P

LINK(LOC(AVAIL)) = AVAIL이라 가정

A1.[초기화] Q ← LOC(AVAIL)

A2.[목록의 끝?] P ← LINK(Q) if (P == Λ) {FAIL!}

A3.[SIZE가 충분한가?] if (SIZE(P)≥N) {goto A4} else { Q ← P, goto A2 }

A4.[N만큼 예약] K ← SIZE(P) – N if (K == 0) {LINK(Q) ← LINK(P)} else {SIZE(P) ← K}

AVAIL

Q

P

공간이 부족하다고 가정하고 진행

A1.[초기화] Q ← LOC(AVAIL)

A2.[목록의 끝?] P ← LINK(Q) if (P == Λ) {FAIL!}

A3.[SIZE가 충분한가?] if (SIZE(P)≥N) {goto A4} else { Q ← P, goto A2 }

A4.[N만큼 예약] K ← SIZE(P) – N if (K == 0) {LINK(Q) ← LINK(P)} else {SIZE(P) ← K}

AVAIL

Q

P

사이즈가 충분하다고 가정 goto A4

A1.[초기화] Q ← LOC(AVAIL)

A2.[목록의 끝?] P ← LINK(Q) if (P == Λ) {FAIL!}

A3.[SIZE가 충분한가?] if (SIZE(P)≥N) {goto A4} else { Q ← P, goto A2 }

A4.[N만큼 예약] K ← SIZE(P) – N if (K == 0) {LINK(Q) ← LINK(P)} else {SIZE(P) ← K}

AVAIL

Q

P

공간이 남으면 SIZE만 업데이트 남지 않으면 블록 제거

좀 낭비하고 세부 사항 처리 부하 줄이기

SIZE(P)가 N+1과 같다면 크기가 1인 블록이 남는다.

쓰지도 못하고 세부 사항 처리 부하만 생김

안 써도 보너스로 붙여서 할당해버림

A4 단계를 변경

P509

예약 최초 적합법

해제 정렬된 목록을 이용한 해제

단짝buddy 시스템 단짝 시스템 예약

단짝 시스템 해제

50 퍼센트 규칙

쓰레기 수거 garbage collection 기법

현재 쓰이고 있는 모든 영역을 쉽게 찾기 X

메모리가 거의 차 있을 때에는 느려지는 경향

메모리를 필요 이상으로 잘게 분할

병합 문제

인접한 두 자유 영역을 하나로 합치기

쓰레기 수거 기법에 의존하지 않으려면 해결해야 함

세 영역을 합치기

두 가용 블록들로 감싸진 한 영역이 자유로워질 때

균형 잡힌 메모리 구성 (50퍼센트 규칙 참고)

예약 최초 적합법

해제 정렬된 목록을 이용한 해제

단짝buddy 시스템 단짝 시스템 예약

단짝 시스템 해제

50 퍼센트 규칙

어려워

반환된 블록의 양쪽 영역들이 사용 가능한지 판정

정렬된 AVAIL 목록

메모리 장소가 증가하는 순으로 유지

해결책

B1.[초기화] Q ← LOC(AVAIL)

B2.[P 전진] P ← LINK(Q) if (P==Λ || P > P0) {goto B3} else {Q ← P, goto B2}

B3.[상계 점검] if (P0+N==P && P!=Λ) {N←N+SIZE(P), LINK(P0)←LINK(P)} else {LINK(P0) ← P}

B4.[하계 점검] if (Q+SIZE(Q)==P0){SIZE(Q)←SIZE(Q)+N, LINK(Q)←LINK(P0)} else {LINK(Q)←P0, SIZE(P0)←N}

AVAIL 목록이 메모리 장소를 기준으로 정렬 LINK(P) != Λ 이면 LINK(P) > P P0에서 시작해 크기가 N인 블록을 AVAIL 목록에 추가

B1.[초기화] Q ← LOC(AVAIL)

B2.[P 전진] P ← LINK(Q) if (P==Λ || P > P0) {goto B3} else {Q ← P, goto B2}

B3.[상계 점검] if (P0+N==P && P!=Λ) {N←N+SIZE(P), LINK(P0)←LINK(P)} else {LINK(P0) ← P}

B4.[하계 점검] if (Q+SIZE(Q)==P0){SIZE(Q)←SIZE(Q)+N, LINK(Q)←LINK(P0)} else {LINK(Q)←P0, SIZE(P0)←N}

AVAIL

Q SIZE = N

AVAIL 목록에 추가할 블록 P0

B1.[초기화] Q ← LOC(AVAIL)

B2.[P 전진] P ← LINK(Q) if (P==Λ || P > P0) {goto B3} else {Q ← P, goto B2}

B3.[상계 점검] if (P0+N==P && P!=Λ) {N←N+SIZE(P), LINK(P0)←LINK(P)} else {LINK(P0) ← P}

B4.[하계 점검] if (Q+SIZE(Q)==P0){SIZE(Q)←SIZE(Q)+N, LINK(Q)←LINK(P0)} else {LINK(Q)←P0, SIZE(P0)←N}

AVAIL

Q SIZE = N

P0

P

B1.[초기화] Q ← LOC(AVAIL)

B2.[P 전진] P ← LINK(Q) if (P==Λ || P > P0) {goto B3} else {Q ← P, goto B2}

B3.[상계 점검] if (P0+N==P && P!=Λ) {N←N+SIZE(P), LINK(P0)←LINK(P)} else {LINK(P0) ← P}

B4.[하계 점검] if (Q+SIZE(Q)==P0){SIZE(Q)←SIZE(Q)+N, LINK(Q)←LINK(P0)} else {LINK(Q)←P0, SIZE(P0)←N}

AVAIL

Q SIZE = N

P0

P

B1.[초기화] Q ← LOC(AVAIL)

B2.[P 전진] P ← LINK(Q) if (P==Λ || P > P0) {goto B3} else {Q ← P, goto B2}

B3.[상계 점검] if (P0+N==P && P!=Λ) {N←N+SIZE(P), LINK(P0)←LINK(P)} else {LINK(P0) ← P}

B4.[하계 점검] if (Q+SIZE(Q)==P0){SIZE(Q)←SIZE(Q)+N, LINK(Q)←LINK(P0)} else {LINK(Q)←P0, SIZE(P0)←N}

AVAIL

Q SIZE = N + SIZE(P)

P0

P

B1.[초기화] Q ← LOC(AVAIL)

B2.[P 전진] P ← LINK(Q) if (P==Λ || P > P0) {goto B3} else {Q ← P, goto B2}

B3.[상계 점검] if (P0+N==P && P!=Λ) {N←N+SIZE(P), LINK(P0)←LINK(P)} else {LINK(P0) ← P}

B4.[하계 점검] if (Q+SIZE(Q)==P0){SIZE(Q)←SIZE(Q)+N, LINK(Q)←LINK(P0)} else {LINK(Q)←P0, SIZE(P0)←N}

SIZE = N + SIZE(P) + SIZE(Q)

AVAIL

Q SIZE = N + SIZE(P)

P0

B1.[초기화] Q ← LOC(AVAIL)

B2.[P 전진] P ← LINK(Q) if (P==Λ || P > P0) {goto B3} else {Q ← P, goto B2}

B3.[상계 점검] if (P0+N==P && P!=Λ) {N←N+SIZE(P), LINK(P0)←LINK(P)} else {LINK(P0) ← P}

B4.[하계 점검] if (Q+SIZE(Q)==P0){SIZE(Q)←SIZE(Q)+N, LINK(Q)←LINK(P0)} else {LINK(Q)←P0, SIZE(P0)←N}

병합하지 못할 때, 링크를 이어주고 사이즈 조정 즉, 사이에 예약된 공간이 있을 때 처리

AVAIL 목록 검색이 필수인 알고리즘

평균적으로 AVAIL 목록의 반정도

검색이 필요 없는 알고리즘은 없을까?

이중 연결 방식 AVAIL 목록, TAG 필드 사용으로 가능

P512

예약 최초 적합법

해제 정렬된 목록을 이용한 해제

단짝buddy 시스템 단짝 시스템 예약

단짝 시스템 해제

50 퍼센트 규칙

모든 블록의 길이가 2의 거듭제곱

계층적으로 블록을 둘로 나눔

요청한 크기에 맞을 때까지

나누어서 생긴 두 블록들을 단짝buddy이라고 부름

36인데, 4를 요청한다면

36 → 16 + 16, 16 → 8 + 8, 8 → 4 + 4

4는 예약된 블록,

16, 8, 4 는 자유 블록

단짝 주소를 쉽게 알 수 있다.

블록의 주소와 블록의 크기를 알아야 함

주소가 101110010110000 블록에서 크기가 16인 단짝은?

101110010100000

예약 최초 적합법

해제 정렬된 목록을 이용한 해제

단짝buddy 시스템 단짝 시스템 예약

단짝 시스템 해제

50 퍼센트 규칙

R1.[블록을 찾는다] k≤j ≤m이며 AVAILF[j]≠LOC(AVAIL[j])가 되는 j를 찾음

R2.[목록에서 제거] L ← AVAILF[j], P ← LINKF[L], AVAILF[j] ← P LINKB(P) ← LOC(AVAIL[j]), TAG(L) ← 0

R3.[분할이 필요한가?] if (j==k)이면 끝

R4.[분할한다] j ← j-1, P←L+2𝑗,TAG(P)←1,KVAL(P)←j, LINKF(P)←LINKB(P)←LOC(AVAIL[j]), AVAIL[j]←AVAILB[j]←P goto R3

R1.[블록을 찾는다] k≤j ≤m이며 AVAILF[j]≠LOC(AVAIL[j])가 되는 j를 찾음

R2.[목록에서 제거] L ← AVAILF[j], P ← LINKF[L], AVAILF[j] ← P LINKB(P) ← LOC(AVAIL[j]), TAG(L) ← 0

R3.[분할이 필요한가?] if (j==k)이면 끝

R4.[분할한다] j ← j-1, P←L+2𝑗,TAG(P)←1,KVAL(P)←j, LINKF(P)←LINKB(P)←LOC(AVAIL[j]), AVAIL[j]←AVAILB[j]←P goto R3

분할이 안 된 자유 블록이 있다고 가정 크기는 4. 즉 22. m=2 크기가 2인 블록을 할당 받고 싶다고 한다. 즉, k=1 분할이 안 됐기 때문에 j=2.

R1.[블록을 찾는다] k≤j ≤m이며 AVAILF[j]≠LOC(AVAIL[j])가 되는 j를 찾음

R2.[목록에서 제거] L ← AVAILF[j], P ← LINKF[L], AVAILF[j] ← P LINKB(P) ← LOC(AVAIL[j]), TAG(L) ← 0

R3.[분할이 필요한가?] if (j==k)이면 끝

R4.[분할한다] j ← j-1, P←L+2𝑗,TAG(P)←1,KVAL(P)←j, LINKF(P)←LINKB(P)←LOC(AVAIL[j]), AVAIL[j]←AVAILB[j]←P goto R3

AVAIL 목록에서 블록을 제거 L은 찾아서 예약한 블록

R1.[블록을 찾는다] k≤j ≤m이며 AVAILF[j]≠LOC(AVAIL[j])가 되는 j를 찾음

R2.[목록에서 제거] L ← AVAILF[j], P ← LINKF[L], AVAILF[j] ← P LINKB(P) ← LOC(AVAIL[j]), TAG(L) ← 0

R3.[분할이 필요한가?] if (j==k)이면 끝

R4.[분할한다] j ← j-1, P←L+2𝑗,TAG(P)←1,KVAL(P)←j, LINKF(P)←LINKB(P)←LOC(AVAIL[j]), AVAIL[j]←AVAILB[j]←P goto R3

j를 1 줄이고 단짝으로 블록을 나눈다. L은 단짝 중 예약된 블록이고 P는 가용한 블록으로 만든다. P는 AVAIL[j] 목록에 넣는다.

예약 최초 적합법

해제 정렬된 목록을 이용한 해제

단짝buddy 시스템 단짝 시스템 예약

단짝 시스템 해제

50 퍼센트 규칙

S1.[단짝이 가용인가?] P ← 𝑏𝑢𝑑𝑑𝑦𝑘(L) if ((k=m || TAG(P) == 0) || (TAG(P)==1 && KVAL(P)≠k) {goto S3}

S2.[단짝과 합친다] LINKF(LINKB(P))←LINKF(P),LINKB(LINKF(P)←LINKB(P) k←k+1, if(P<L) {L←P} goto S1

S3.[목록에 추가] TAG(L)←1, P←AVAILF[k], LINKF(L) ←P, LINKB(P)←L KVAL(L)←k, LINKB(L)←LOC(AVAIL[k]),AVAIL[k]←L

S1.[단짝이 가용인가?] P ← 𝑏𝑢𝑑𝑑𝑦𝑘(L) if ((k=m || TAG(P) == 0) || (TAG(P)==1 && KVAL(P)≠k) {goto S3}

S2.[단짝과 합친다] LINKF(LINKB(P))←LINKF(P),LINKB(LINKF(P)←LINKB(P) k←k+1, if(P<L) {L←P} goto S1

S3.[목록에 추가] TAG(L)←1, P←AVAILF[k], LINKF(L) ←P, LINKB(P)←L KVAL(L)←k, LINKB(L)←LOC(AVAIL[k]),AVAIL[k]←L

단짝이 예약됐다면 k=m, 즉 최고 큰 블록이라면 합치지 않고 S3로 가서 목록에 추가하고 끝

S1.[단짝이 가용인가?] P ← 𝑏𝑢𝑑𝑑𝑦𝑘(L) if ((k=m || TAG(P) == 0) || (TAG(P)==1 && KVAL(P)≠k) {goto S3}

S2.[단짝과 합친다] LINKF(LINKB(P))←LINKF(P),LINKB(LINKF(P)←LINKB(P) k←k+1, if(P<L) {L←P} goto S1

S3.[목록에 추가] TAG(L)←1, P←AVAILF[k], LINKF(L) ←P, LINKB(P)←L KVAL(L)←k, LINKB(L)←LOC(AVAIL[k]),AVAIL[k]←L

AVAIL[k] 목록에서 블록 P를 제거 L이 합쳐진 단짝 처음을 가리킨다.

S1.[단짝이 가용인가?] P ← 𝑏𝑢𝑑𝑑𝑦𝑘(L) if ((k=m || TAG(P) == 0) || (TAG(P)==1 && KVAL(P)≠k) {goto S3}

S2.[단짝과 합친다] LINKF(LINKB(P))←LINKF(P),LINKB(LINKF(P)←LINKB(P) k←k+1, if(P<L) {L←P} goto S1

S3.[목록에 추가] TAG(L)←1, P←AVAILF[k], LINKF(L) ←P, LINKB(P)←L KVAL(L)←k, LINKB(L)←LOC(AVAIL[k]),AVAIL[k]←L

블록 L을 AVAIL[k] 목록에 넣는다.

예약 최초 적합법

해제 정렬된 목록을 이용한 해제

단짝buddy 시스템 단짝 시스템 예약

단짝 시스템 해제

50 퍼센트 규칙

1

2𝑝𝑁

평형 상태로 가는 경향이 생기도록 알고리즘 A와 B를 연속해서 사용한다면

가용 블록의 평균 개수는

𝑁 – 시스템 예약된 블록들 평균 개수 𝑝 – 알고리즘 A의 수량 K가 0이 아닐 확률 재사용될 가능성이 낮은 수량.

증명

p516

시뮬레이션

p517 ~ p522

예약 최초 적합법

해제 정렬된 목록을 이용한 해제

단짝buddy 시스템 단짝 시스템 예약

단짝 시스템 해제

50 퍼센트 규칙