메모리풀 구현에 대한 질문입니다.
글쓴이: superkkt / 작성시간: 토, 2006/06/17 - 5:52오후
메모리풀을 구현해 보려고 생각을 좀 해봤는데 궁금한점이 있어서 질문 올립니다. 10MB의 메모리를 미리 할당받아놓고 아래와 같이 풀에서 3개의 메모리를 할당했을때..
A(1MB) | B(2MB) | C(3MB) | 할당되지 않은 공간(4MB)
B가 사용을 마치고 반환을 했습니다.
A(1MB) | 할당되지 않은 공간(2MB) | C(3MB) | 할당되지 않은 공간(4MB)
그후에 다시 3MB의 할당요청이 들어오면 이전의 B자리에는 공간이 부족해서 할당을 할수가 없습니다. 그렇다고 B자리에 2MB, 맨뒤 빈공간에 1MB를 할당해서 돌려줄수도 없구요.. 그렇다면 2MB 이하의 할당요청이 오기전까지는 B 자리는 사용을 할 수 없다는 얘긴데요.
이런 과정이 여러번 반복되면(특히 작은 크기의 메모리 할당이 빈번하게 발생했을때) 빈 공간은 많이 있어도 모두 쪼개져 있어서 메모리풀을 확장해야 하는 경우가 자주 발생될걸로 생각됩니다. 이 문제를 어떻게 해결해야 하나요? 가비지 콜렉션이란게 이럴때 사용되는 방법인가요?
조각모음(?)을 한답시고 C를 B자리로 memmove를 시켜버리면 C의 메모리 주소가 바뀌기 때문에 안될테구요.. 흠.. 그냥 메모리풀 얘기를 들을때는 그런게 있구나 하다가 직접 구현해 보려니 어렵네요.
Forums:
physical하게 연속이
physical하게 연속이 아니라도 logical하게 연속이 되도록 MMU를 사용하는 방법이 있을 수 있을 듯 합니다. 그리고 fragmentation 문제가 걱정이 되는 메모리를 할당할 때는 할당한 후에 메모리를 address로 직접 접근하지 않고 메모리를 뭔가 설정된 offset을 이용해서 접근하도록 하는 것도 해결방법이 될 수 있습니다. 나중에 fragmentation문제가 발생해서 memory의 내용을 옮기고 싶을 때 memory를 옮긴 다음에 해당 offset만 변경시켜 주면 됩니다. 단, 이 경우에는 MT-Safe하지 않기 때문에(offset을 이용해서 memory에 접근하고 있는데 offset이 다른 thread에 의해 변경되는 등의 상황이 존재) critical section을 적절히 보호해 줘야 됩니다.
Taeho Oh ( ohhara@postech.edu, ohhara@plus.or.kr ) http://ohhara.sarang.net
Postech ( Pohang University of Science and Technology ) http://www.postech.edu
PLUS ( Postech Laboratory for Unix Security ) http://www.plus.or.kr
Taeho Oh ( ohhara@postech.edu ) http://ohhara.sarang.net
Postech ( Pohang University of Science and Technology ) http://www.postech.edu
Alticast Corp. http://www.alticast.com
Modern C++ Design -
Modern C++ Design - 안드레 알렉산드레스쿠 저 , 인포북
라는 번역본 책이 있습니다.
그 책에 메모리풀의 설명부터, 주의 사항, 다양한 구현방법, 구현에 따른 특징 등이 잘 설명되어 있습니다.
메모리풀이 아니여도 추천할만한 책이니깐 함 봐보세요.
메모리 단편화는 오래전의 컴퓨터에서 이슈화 됐던 일이죠.
그 해결법으로 페이징기법을 사용하게 된거지요.
그래서 페이징기법이 도입된 이후 메모리단편화에 의한 문제를 접하기가 힘들죠.
요즘은 페이징 기법이 적용안된 작은 임베디드 시스템에서 다시 이슈화가 조금 되고 있기도 합니다.
가비지 콜렉션은 메모리단편화와는 다른 이슈이죠.
두분 답변
두분 답변 감사합니다. ssehoony님이 알려주신 책은 꼭 사서 읽어봐야겠습니다. 답변을 보고 생각을 해보면서 또 궁금한 점이 생겼는데요..
메모리풀은 빈번하게 메모리를 할당하고 해제하는 프로그램에서 성능 향상을 위해 미리 큰 사이즈의 메모리를 할당한 후 논리적으로 분배해서 사용하는 기술인걸로 알고 있습니다.
그런데 ohhara님이 설명해주신 방법은 OS가 메모리를 관리하는 방법과 유사하다고 생각이 됩니다. 그렇다면 OS 레벨에서 이미 수행되는 기능을 메모리 풀 구현을 위해 어플리케이션 레벨에서 다시 한번 수행하는것이 되는데 이렇게하면 정말 성능 향상이 있을 수 있는지가 궁금하네요.
음.. 엄밀히 말하면 처음에 대량으로 메모리를 할당받을때만 중복되는 기능을 수행하고 다음부터는 어플리케이션 레벨에서 메모리를 관리하겠군요. 하지만 단편화된 메모리를 정리하고 물리적인 메모리 주소를 논리적으로 매핑시키는 기능 구현등이 OS에서 제공하는 기능만큼 효율적인 코드를 작성하기가 힘들텐데요..
이런 오버헤드(?)를 감안했을때 어떤 경우에 메모리 풀을 사용하는것이 효율적이고 대략 어느 정도의 성능 향상을 기대할 수 있을까요?
======================
BLOG : http://superkkt.com
======================
BLOG : http://superkkt.com
메모리풀이 하는
메모리풀이 하는 역할은 말씀하신대로 대략 OS가 하는 것과 비슷합니다.
하지만 OS가 하는 것은 일단 시스템콜이라는 이유로 늦고, 다른 프로세스와의 싱크 문제가 있어서 싱크관리해도 해야 하고(멀티프로세서일경우는 싱크가 더 복잡해지죠), 상당히 제너럴하게 구현되고, 메모리 페이징 테이블 업데이트 등등의 이유로 많은 오버헤드가 발생하게 되는데요.
메모리풀은 일단 큰 메모리를 한번에 가져오면, OS가 메모리 할당할때하는 복잡한것은 안해도 되니깐 불필요한 작업을 제거해서 최적화하는 것이지요.
그리고 OS로 부터 큰메모리를 가져오는 것과 작은 것을 가져오는 속도는 비슷하다는 것. OS로부터 메모리 할당 부하는 용량 아니고 회수의 문제라는 것.
메모리풀도 멀티쓰레드 환경을 위해 mutex lock 을 사용하긴 하지만, MT 환경에서는 lock은 매우 빨라서, OS의 프로세스간 싱크 오버헤드와 비교가 안될 정도로 가볍다.
메모리풀로 볼수 있는 효과는 new/delete, malloc/free 가 많으면 많을 수록 빠릅니다.
단순하게 링크드리스트에 int 등과 같은 primitive type 데이터를 담는 노드를 계속 추가하는 작업을 하는 코드만 따진다면, 수백% 빨라질겁니다.
메모리풀도 좋지만, 가장 중요한건 stack 으로 해결할 수 있다면 heap 을 사용하지 않고 stack 으로 해결하는게 가장 좋습니다.
OS의 메모리 할당
OS의 메모리 할당 작업이 이렇게 오버헤드 큰 작업이었군요.. 몰랐습니다. 이제 왜 메모리풀을 사용하는지 이해가 되네요. 그럼 이제 남은건 구현인데.. 심심해서 갑자기 만들어 볼라고 도전한것치곤 너무 어려운것에 도전했다는 생각이 드네요..^^
======================
BLOG : http://superkkt.com
======================
BLOG : http://superkkt.com
A Memory Allocator를 한
A Memory Allocator를 한 번 읽어보기 바랍니다. glibc의 malloc의 모태가 된 dlmalloc에 대한 설명입니다.
구태여 general purpose allocator를 다시 만드는 것은 큰 활용성이 없을지도 모릅니다. 공부하는 차원이라면 모를까.. 차라리 특정 목적에 맞는 allocator를 만들어 보는 것이 더 쉽고 도움이 될 것입니다.
libiberty에 포함된 (glibc에도 포함됨) obstack도 한 번 읽어보기 바랍니다. 짧고, 간단하며, 효과적인 allocator입니다.
Garbage collection에 대한 것은 먼저 이 문서부터 보기 바랍니다.
Uniprocessor Garbage Collection Techniques 실제로 쓸만한? GC 중 유명한 것으로 Boehm-Demers-Weiser conservative garbage collector가 있습니다.
--
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
Korean Ver: http://www.cinsk.org/cfaqs/
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
Korean Ver: http://cinsk.github.io/cfaqs/
댓글 달기