사용자 도구

사이트 도구


kb:memoryallocation

차이

문서의 선택한 두 판 사이의 차이를 보여줍니다.

차이 보기로 링크

kb:memoryallocation [2014/11/08 13:42] (현재)
줄 1: 줄 1:
 +====== Memory Allocation ======
 +메모리 할당에 있어서, 이슈는 2가지라고 볼 수 있다. 첫번째는 스레드 직렬화에 따른 성능 저하, 두번째는 대량의 할당/​해제에 따른 단편화이다. 성능 저하를 피하면서 단편화를 최소화하는 것이 대부분의 범용 메모리 할당 알고리즘들이 추구하는 바이다.
 +
 +
 +====== 2개 이상의 힙을 사용한 메모리 단편화 해결 방안 ======
 +from [[http://​blogs.msdn.com/​ricom/​archive/​2006/​02/​02/​523626.aspx | Unmanaged Memory Fragmentation -- an old story]]
 +
 +요약해보자면...
 +
 +2개의 힙을 할당한 다음 N번째, 예를 들어 100000번째까지는 첫번째 힙에서 계속 할당을 하고, 100001번째부터는 두번째 힙에서 할당을 한다. 그러다 200000번째 할당이 필요하게 되면 다시 첫번째 힙에서부터 할당을 한다. ​
 +
 +<code cpp>
 +static size_t g_Allocs = 0;
 +static int    g_HeapIndex = 0;
 +static HANDLE g_Heap[2] = { NULL, NULL };
 +...
 +void* operator new (size_t size)
 +{
 +    if ((++g_Allocs % 100000) == 0) 
 +        g_HeapIndex ^= 0x10; 
 +
 +    return ::​HeapAlloc(g_Heap[HeapIndex],​ HEAP_ZERO_MEMORY,​ size);
 +}
 +</​code>​
 +''​대충 이런 식?''​
 +
 +이와 같은 방법으로 메모리 할당을 하게 되면 한쪽에서는 할당만이 일어나고,​ 나머지 한쪽에서는 해제만이 일어나게 된다. 다른 쪽의 힙에서 할당을 하게 될 때쯤 되면, 그 힙은 거의 깨끗한 상태가 된다는 말이다. ​
 +
 +물론 애플리케이션의 특성에 따라 달라지기는 하겠으나,​ 힙에 올라가는 데이터들이 금방 사라지는 데이터라는 점을 감안하면 괜찮을 것 같기도 하다. 장기간 힙에 존재하는 데이터의 경우(룩업테이블 같은...)에는 따로 힙을 마련해두면 그만. 문제는 저 100000이라는 숫자를 어떻게 정하느냐인데... 힙에 올라가는 데이터의 평균 수명과 초당 할당 호출 횟수를 알아내야하나?​
 +
 +
 +====== Multi-Processor Heap ======
 +Visual C++ 6.0 샘플에 있던 소스로서,​ 멀티 프로세서 머신에서 돌아가는 멀티 스레드 프로그램의 성능 개선을 위한 메모리 할당 알고리즘이다. Visual C++ 6.0 샘플은 [[http://​www.microsoft.com/​downloads/​details.aspx?​FamilyId=AF0A6060-6566-408F-9F11-EA2C80B8CAA0&​displaylang=en | 여기]]에서 다운로드받을 수 있다. 소스 원문에 있던 내용을 일부 옮겨보자면 다음과 같다. ​
 +
 +//Many multithreaded applications that use the standard memory allocation routines (malloc/​free,​ LocalAlloc/​LocalFree,​ HeapAlloc/​HeapFree) suffer a significant performance penalty when running on a/ multi-processor machine. ​ This is due to the serialization used by the default heap package. ​ On a multiprocessor machine, more than one thread may simultaneously try to allocate memory. ​ One thread will block on the critical section guarding the heap.  The other thread must then signal the critical section when it is finished to unblock the waiting thread. ​ The additional codepath of blocking and signalling adds significant overhead to the frequent memory allocation path.//
 +
 +//By providing multiple heaps, this DLL allows simultaneous operations on each heap.  A thread on processor 0 can allocate memory from one heap at the same time that a thread on processor 1 is allocating from a different heap.  The additional overhead in this DLL is compensated by drastically reducing the number of times a thread must wait for heap access.//
 +
 + 
 +====== Windows XP Low-fragmentation Heap ======
 +[[http://​msdn.microsoft.com/​library/​default.asp?​url=/​library/​en-us/​memory/​base/​low_fragmentation_heap.asp | Low-fragmentation Heap]]
 +
 +윈도우즈 XP 이상의 버전에서는 HeapSetInformation API를 이용해 단편화를 줄일 수 있다.
 +
 +<code cpp>
 +#include <​windows.h>​
 +#include <​stdio.h>​
 +
 +void main()
 +{
 +    ULONG  HeapFragValue = 2;
 +
 +    if(HeapSetInformation(GetProcessHeap(),​
 +                       ​HeapCompatibilityInformation,​
 +                       &​HeapFragValue,​
 +                       ​sizeof(HeapFragValue))
 +    )
 +    {
 +        printf("​Success!\n"​);​
 +    }
 +    else printf ("​Failure (%d)\n",​ GetLastError());​
 +}
 +</​code>​
 +
 +API 한번 호출해주면 땡이니, 별다른 수고 없이 단편화를 줄일 수 있는 셈이다. 그러나 세상 만사 그리 쉬울 리 없다. 이 기능은 해당 힙에 HEAP_NO_SERIALIZE 같은 플래그들이 켜져 있는 경우에는 동작하지 않는다. 디버그 버전일 때도 안 돌아가는 모양이다. 사용할 일이 있기는 할지 의문이다. ​
 +
 +
 +====== 링크 ======
 +  * [[http://​www.cs.umass.edu/​~emery/​hoard/​ | the HOARD memory allocator]] \\ The Hoard memory allocator is a fast, scalable, and memory-efficient memory allocator. It runs on a variety of platforms, including Linux, Solaris, and Windows. Hoard is a drop-in replacement for malloc() that can dramatically improve application performance,​ especially for multithreaded programs running on multiprocessors. No change to your source is necessary. Just link it in or set just one environment variable.
 +  * [http://​g.oswego.edu/​dl/​html/​malloc.html] \\ Doug Lea's malloc
 +  * [[http://​rtportal.upv.es/​rtmalloc/​ | Real-Time Dynamic Memory Allocation]] \\ This is a web site dedicated to explicit dynamic storage allocation in the area of real-time systems. Although dynamic storage allocation is a deeply studied subject in computer science, it has not been widely used in real-time systems due to the commonly accepted idea that it is, due to the intrinsic nature of the problem, difficult or even impossible to design a efficient time-bounded algorithm.
 +  * [[http://​www.gamasutra.com/​features/​20020802/​hixon_01.htm | Gamasutra > Play by Play : Effective Memory Management]] \\ 메모리 관리자를 직접 제작할 때 생각해야할 문제점들
 +  * [[http://​devnet.developerpipeline.com/​documents/​s=9843/​cuj0512alexandrescu/​ | Policy-Based Memory Allocation]]
 +
 +----
 +  * see also [[MemoryManagement]]
  
kb/memoryallocation.txt · 마지막으로 수정됨: 2014/11/08 13:42 (바깥 편집)