|
¿À´Ã ¸¶Áö¸· MemPool ±¸Çö±îÁö ¿Ã¸³´Ï´Ù. ^^
MemPoolSize - ºñ½ÁÇÑ Å©±âÀÇ Å¬·¡½ºµé³¢¸® °°Àº PoolÀ» ¾²´Â MemPool
¼·Ð
ÀÌÁ¦ ¸¶Áö¸·À¸·Î °¡Àå º¹ÀâÇÏ°í °¡Àå ¹ü¿ëÀûÀÎ MemPoolÀÎ MemPoolSize¿¡ ´ëÇØ ¾Ë¾Æº¸°Ú½À´Ï´Ù. ¸î¸î ÇÁ·ÎÁ§Æ®¿¡¼
¾Õ¿¡¼ ÀÛ¼ºÇÑ MemPoolClass¿Í MemPoolShareµéÀ» »ç¿ëÇÏ¿© º» ÈÄ ¸Å¿ì ¸¶À½¿¡ µé¾ú´Ù°í °¡Á¤ÇÕ´Ï´Ù. ÀÌÁ¦
ÇÁ·ÎÁ§Æ®ÀÇ ¸ðµç Ŭ·¡½ºµéÀ» MemPool¿¡¼ »ó¼Ó¹Þ¾Æ »ç¿ëÇÏ·Á°í ÇÕ´Ï´Ù. ÇÏÁö¸¸ ÀÌ °æ¿ì ¸î°¡Áö ¹®Á¦°¡ ÀÖ½À´Ï´Ù.
¸ÕÀú MemPoolClass¸¦ »ç¿ëÇÒ °æ¿ì °¢ Ŭ·¡½º´Â ÀڽŸ¸ÀÇ poolÀ» °¡Áö°Ô µË´Ï´Ù. ¹®Á¦´Â µ¿½Ã¿¡ ÇÑ
µÎ°³ÀÇ instance¸¸ ÇÊ¿äÇÑ Å¬·¡½ºµéµµ ¸ðµÎ 50°³(default)¾¿ÀÇ ¸Þ¸ð¸®¸¦ Â÷ÁöÇÏ°Ô µÈ´Ù´Â °ÍÀÔ´Ï´Ù. ¹°·Ð »ç¿ëÀÚ°¡
Ŭ·¡½ºÀÇ Á¾·ù¿¡ µû¶ó Àû´çÇÑ °ªÀ» ÁÙ ¼ö´Â ÀÖÁö¸¸ ¾î¶² Ŭ·¡½º°¡ ¸î°³³ª »ç¿ëµÉÁö ¹Ì¸® ¾Ë±âµµ ¾î·Á¿ï °ÍÀÔ´Ï´Ù.
±×¸®°í MemPoolShareÀÇ °æ¿ì´Â ¸ðµç Ŭ·¡½ºÁß¿¡ °¡Àå Å« Ŭ·¡½ºÀÇ Å©±â¸¦ ±âÁØÀ¸·Î ÇØ¾ß ÇϹǷΠ¸Þ¸ð¸® ³¶ºñ°¡ ³Ê¹« ½ÉÇÕ´Ï´Ù.
µû¶ó¼ Å©±âº°·Î poolÀ» ¸î°³ ¸¸µé¾î ³õ°í ƯÁ¤ Ŭ·¡½º´Â ÀÌ poolµé Áß ÀÚ½ÅÀÇ Å©±â¿¡ Àû´çÇÑ poolÀ»
»ç¿ëÇÏ´Â MemPoolÀ» ¸¸µé¾î º¸µµ·Ï ÇϰڽÀ´Ï´Ù. À̶§ ÀÚ½ÅÀÇ Å©±â¿¡ Àû´çÇÑ poolÀ» ã´Â ÀÛ¾÷Àº ¸ðµÎ ÄÄÆÄÀÏ ½Ã°£¿¡ ÇÏ¿©
runtime overhead´Â ÀüÇô ¾øµµ·Ï ÀÛ¼ºÇÕ´Ï´Ù.
»ó¼¼ ±¸Çö
Singleton »ç¿ë
¸ÕÀú °í·ÁÇÒ »çÇ×Àº À̹ø¿¡ ¸¸µé MemPoolÀº ƯÁ¤ Ŭ·¡½º¿¡ µû¶ó ±¸ÇöÀ» ´Ù¸£°Ô »ç¿ëÇÏ´Â °ÍÀÌ ¾Æ´Ï¶ó °øÅë ±¸ÇöÀ» ¸ðµç
Ŭ·¡½º°¡ »ç¿ëÇØ¾ß ÇÕ´Ï´Ù. µû¶ó¼ ÀÌ °øÅë ±¸ÇöÀ» À§ÇØ MemPoolÀ» ´Ù·ç´Â Singleton °´Ã¼°¡ ÇÊ¿äÇÕ´Ï´Ù. ¿©±â¼´Â
Singleton ±¸ÇöÀ» À§ÇØ °£´ÜÇÑ SingletonHolder Ŭ·¡½º¸¦ ¸¸µé¾î »ç¿ëÇÕ´Ï´Ù. Modern C++ Design
¿¡ ³ª¿Ô´ø °Í°ú °°Àº ±â´ÉÀÌ ¸¹Àº Ŭ·¡½º¸¦ °¡Á®¿Í »ç¿ëÇÒ ¼öµµ ÀÖÀ¸³ª ¿©±â¼ »ç¿ëÇÒ SingletonHolder´Â ¸¹Àº ±â´ÉÀÌ
ÇÊ¿äÇÏÁö ¾Ê±â ¶§¹®¿¡ °£´ÜÇÏ°Ô ¸¸µé¾ú½À´Ï´Ù.
template <class T, class LockModel>
class SingletonHolder : public LockModel
{
public:
static T* instance() {
if (pthis_ == 0) {
Lock lk; lk;
if (pthis_ == 0) {
pthis_ = new T;
}
}
return pthis_;
}
private:
SingletonHolder();
~SingletonHolder();
SingletonHolder(const SingletonHolder& );
SingletonHolder& operator=(const SingletonHolder& );
static T* pthis_;
};
template <class T, class LockModel>
T* SingletonHolder<T, LockModel>::pthis_;
|
Äڵ忡¼ º¸ÀÌ´Â ¹Ù¿Í °°ÀÌ ¸Å¿ì °£´ÜÇÑ ÄÚµåÀÔ´Ï´Ù. LockModelÀ» »ç¿ëÇÏ¿© Double-Checked-Locking ÆÐÅÏÀ» »ç¿ëÇß½À´Ï´Ù.
ÀÌ SingletonHolder¸¦ »ç¿ëÇÏ¿© ´ÙÀ½°ú °°ÀÌ °øÅëÀ¸·Î »ç¿ëÇÒ MemPool ±¸ÇöÀ» ¸¸µì´Ï´Ù. ¿©±â¼´Â ±¸Çö Ŭ·¡½ºÀÇ À̸§À» ChunkAllocatorImplÀ̶ó°í ÇÏ¿´½À´Ï´Ù.
template <
...
class LockModel
>
class ChunkAllocatorImpl : public LockModel
{
|
±×¸®°í SingletonÀ¸·Î »ç¿ëÇÒ¶§´Â ´ÙÀ½°ú °°ÀÌ ¼±¾ðÇÏ¿© »ç¿ëÇÕ´Ï´Ù.
typedef SingletonHolder<ChunkAllocatorImpl, LockModel> ChunkAllocator;
|
PoolµéÀÇ Å©±â
´ÙÀ½À¸·Î °í·ÁÇÒ »çÇ×Àº poolµéÀ» ¸¸µé¶§ ¾î¶² ±âÁØÀ¸·Î Å©±â¸¦ ÀâÀ»±î ÇÏ´Â °ÍÀÔ´Ï´Ù. ¿©±â¼´Â »ç¿ëÀÚ°¡ poolÀÇ ÃÖ¼Ò, ÃÖ´ë Å©±â¸¦ ÁöÁ¤ÇÒ ¼ö ÀÖ´Â ´ÙÀ½°ú °°Àº ¹æ¹ýÀ» »ç¿ëÇÕ´Ï´Ù.
- »ç¿ëÀÚ´Â ÃÖ¼Ò, ÃÖ´ë Å©±â¸¸À» ÁöÁ¤ÇÕ´Ï´Ù.
- ¸ÕÀú poolÀÇ Å©±â°¡ ÃÖ¼Ò°ªÀÎ poolÀ» ¸¸µì´Ï´Ù.
- ¾ÕÀÇ Å©±â¿¡ 2¸¦ °öÇÑ Å©±âÀÇ poolÀ» ¸¸µì´Ï´Ù.
- À§¸¦ Å©±â°¡ ÃÖ´ë°ªÀÌ µÉ¶§±îÁö ¹Ýº¹ÇÏ¿© poolÀ» ¸¸µì´Ï´Ù.
Áï, ÃÖ¼Ò°ªÀÌ 32, ÃÖ´ë°ªÀÌ 4096ÀÏ °æ¿ì ´ÙÀ½°ú °°Àº Å©±â¸¦ °¡Áø 8°³ÀÇ poolÀÌ ¸¸µé¾îÁý´Ï´Ù.
32, 64, 128, 256, 512, 1024, 2048, 4096
|
ÀÌ ¹æ¹ýÀ» »ç¿ëÇϱâ À§ÇØ ÃÖ´ë°ªÀº ÃÖ¼Ò°ªÀÇ 2ÀÇ ÀÚ½ÂÀ¸·Î Ç¥ÇöµÇ´Â ¼ýÀÚ¿©¾ß ÇÕ´Ï´Ù. (4096 = 32 * 27)
±×·³ »ç¿ëÀڷκÎÅÍ ÃÖ¼Ò°ª, ÃÖ´ë°ªÀ» ¹Þ¾ÒÀ» ¶§ ¸î°³ÀÇ poolÀÌ ÇÊ¿äÇÑÁö¸¦ ÄÄÆÄÀÏ ½Ã°£¿¡ ¾Ë·Á¸é ¾î¶»°Ô ÇØ¾ß ÇÒ±î¿ä? °£´ÜÇÏ°Ô 4096À» °è¼Ó 2·Î ³ª´©¾î 32°¡ µÇ·Á¸é ¸î ¹øÀ̳ª ³ª´©¾î¾ß µÇ´ÂÁö¸¦ °è»êÇÑ ÈÄ 1À» ´õÇÏ¸é µË´Ï´Ù.
À̸¦ ¼ö½ÄÀ¸·Î Ç¥ÇöÇÏ¸é ´ÙÀ½°ú °°½À´Ï´Ù.
log2(4096) / log2(32) + 1
= log2(4096 / 32) + 1
|
À§ ½ÄÀ» ÄÄÆÄÀÏ ½Ã°£¿¡ °è»êÇϱâ À§ÇØ ´ÙÀ½°ú °°ÀÌ log2¸¦ °è»êÇØ ÁÖ´Â template meta functionÀ» ¸¸µì´Ï´Ù.
template <int N>
struct log_2
{
BOOST_STATIC_ASSERT(N % 2 == 0);
enum {
value = 1 + log_2<N / 2>::value
};
};
template <>
struct log_2<2>
{
enum {
value = 1
};
};
|
µÎ¹øÂ° template specializationÀº loop¸¦ ¸ØÃß±â À§ÇØ ÇÊ¿äÇÕ´Ï´Ù. ¸¸¾à À§ÀÇ ÇÔ¼ö¿¡¼ NÀÌ È¦¼ö¶ó¸é
2ÀÇ ÀÚ½ÂÀ¸·Î Ç¥ÇöµÇÁö ¾Ê´Â ¼ýÀÚÀÓÀ» ³ªÅ¸³»¹Ç·Î ÄÄÆÄÀÏ ¿¡·¯¸¦ ¹ß»ý½Ã۱â À§ÇØ BOOST_STATIC_ASSERT¸¦ »ç¿ëÇÕ´Ï´Ù.
ÀÌ ÇÔ¼ö¸¦ »ç¿ëÇÏ¿© ´ÙÀ½°ú °°ÀÌ POOL_COUNT¸¦ Á¤ÀÇÇϰí ÀÌ °ªÀ» ÀÌ¿ëÇÏ¿© °ªµéÀÇ ¹è¿À» ¼±¾ðÇÕ´Ï´Ù.
template <
int MIN_SIZE,
int MAX_SIZE,
int OBJS_IN_A_BLOCK,
class LockModel
>
class ChunkAllocatorImpl : public LockModel
{
public:
enum {
POOL_COUNT = log_2<MAX_SIZE / MIN_SIZE>::value + 1
};
ChunkAllocatorImpl();
void* allocate(size_t real_size, size_t size, int index);
void deallocate(void* p, size_t real_size, size_t size, int index);
size_t capacity(int index) const;
size_t size(int index) const;
void reserve(int index, size_t size);
private:
void allocate_block(size_t size, int index);
unsigned char* free__[POOL_COUNT];
size_t capacity__[POOL_COUNT];
size_t size__[POOL_COUNT];
};
|
ÀÌ ChunkAllocatorImpl Ŭ·¡½º´Â ±âÁ¸ÀÇ MemPoolClass³ª MemPoolShare¸¦ ±¸ÇöÇÒ¶§ »ç¿ëÇß´ø
¹æ¹ýÀ» ±×´ë·Î »ç¿ëÇÕ´Ï´Ù. capacity, size, reserve ÇÔ¼öµéÀº ÀÌÀü°ú µ¿ÀÏÇÑ ±¸ÇöÀ» »ç¿ëÇϳª ¾î¶² index¿¡
ÀÖ´Â poolÀ» »ç¿ëÇÒÁö¸¦ ¾Ë·ÁÁÖ´Â ÀÎÀÚ¸¦ Ãß°¡·Î °¡Áö°í ÀÖ½À´Ï´Ù.
±×¸®°í allocate³ª deallocate´Â ±âÁ¸ MemPoolÀÇ new, delete¿¡ ÇØ´çÇÏ´Â °ÍÀ¸·Î
real_size ÀÎÀÚ´Â ½ÇÁ¦ Ŭ·¡½ºÀÇ Å©±â¸¦ ³ªÅ¸³»°í index´Â Áö±Ý ÀÌ ÇÔ¼ö¿¡¼ »ç¿ëÇØ¾ß ÇÒ poolÀÇ index¸¦,
±×¸®°í size´Â ÀÌ index¿¡¼ ¾²À̰í ÀÖ´Â Å©±â¸¦ ³ªÅ¸³À´Ï´Ù.
¿¹¸¦ µé¾î 100¹ÙÀÌÆ®Â¥¸® Ŭ·¡½º°¡ »ý¼ºµÇ°í ÀÖ´Ù¸é ´ÙÀ½°ú °°Àº ÀÎÀÚ¸¦ °¡Áö°í allocate°¡ ºÒ¸®°Ô µË´Ï´Ù.
»ý¼ºÀÚ¿¡¼´Â °¢ ¸â¹ö º¯¼öµéÀ» ÃʱâÈÇØÁÝ´Ï´Ù. Ŭ·¡½ºÀÇ static ¸â¹ö º¯¼ö¿Í´Â ´Þ¸® ÀÏ¹Ý ¸â¹ö º¯¼ö´Â ÃʱâȰ¡ ÀÚµ¿À¸·Î µÇÁö ¾Ê±â ¶§¹®¿¡ »ý¼ºÀÚ¿¡¼ ¹Ýµå½Ã ÇØÁÖ¾î¾ß ÇÕ´Ï´Ù.
³ª¸ÓÁö ¼¼ºÎÀûÀÎ ±¸ÇöÀº ±âÁ¸°ú µ¿ÀÏÇϱ⠶§¹®¿¡ ¼³¸íÀº »ý·«ÇϰڽÀ´Ï´Ù.
¸¶Áö¸·À¸·Î ChunkAllocatorImplÀ» Singleton °´Ã¼·Î »ç¿ëÇÏ´Â ChunkAllocator Ŭ·¡½º¸¦
´ÙÀ½°ú °°ÀÌ ±¸ÇöÇÕ´Ï´Ù. ÀÌ Å¬·¡½º´Â ³ªÁß¿¡ MemPoolSizeÀÇ template parameter·Î »ç¿ëµË´Ï´Ù.
template <
int MIN_SIZE,
int MAX_SIZE,
int OBJS_IN_A_BLOCK,
class LockModel
>
class ChunkAllocator
{
public:
typedef ChunkAllocatorImpl<
MIN_SIZE,
MAX_SIZE,
OBJS_IN_A_BLOCK,
LockModel
> ImplType;
typedef SingletonHolder<
ImplType,
LockModel
> Allocator;
static void* allocate(size_t real_size, size_t size, int index) {
return Allocator::instance()->allocate(real_size,
size,
index);
}
static void deallocate(void* p, size_t real_size, size_t size, int index) {
Allocator::instance()->deallocate(p,
real_size,
size,
index);
}
};
|
´Ü¼øÈ÷ ÇÔ¼ö°¡ ºÒ¸®¸é ChunkAllocatorImpl·Î ÀÛ¾÷À» ³Ñ±â´Â Ŭ·¡½ºÀÓÀ» ¾Ë ¼ö ÀÖ½À´Ï´Ù.
MemPoolSize ±¸Çö
´ÙÀ½À¸·Î ½ÇÁ¦ Ŭ·¡½ºµéÀÌ »ó¼Ó¹Þ¾Æ »ç¿ëÇÒ MemPoolSizeÀÇ ±¸ÇöÀ» »ìÆìº¸°Ú½À´Ï´Ù. ¿©±â¼ ChunkAllocator
ÀÎÀÚ´Â À§¿¡¼ ±¸ÇöÇÑ ChunkAllocator Ŭ·¡½º¸¦ ³ªÅ¸³»¸ç default°ªÀ¸·Î ÃÖ¼Ò°ª 32, ÃÖ´ë°ª 4096À» »ç¿ëÇϰí
ÀÖ½À´Ï´Ù.
template <
class T,
class ChunkAllocator = ChunkAllocator<32, 4096, 50, NoLock>
>
class MemPoolSize
{
public:
static void* operator new (size_t size);
static void operator delete (void* p, size_t size);
protected:
~MemPoolSize() {}
};
|
¸¸¾à À̶§ »ó¼Ó¹ÞÀº Ŭ·¡½ºÀÇ Å©±â°¡ ÃÖ´ë°ªÀÎ 4096¹ÙÀÌÆ®¸¦ ³Ñ´Â °æ¿ì¿¡´Â ¾î¶»°Ô ÇØ¾ß ÇÒ±î¿ä? ¿©±â¼´Â ÀÌ·± °æ¿ì
default new, delete¸¦ »ç¿ëÇϵµ·Ï ±¸ÇöÇÕ´Ï´Ù. À̸¦ À§ÇØ ´ÙÀ½°ú °°Àº DefaultAllocator Ŭ·¡½º¸¦
±¸ÇöÇÕ´Ï´Ù.
class DefaultAllocator
{
public:
static void* allocate(size_t real_size, size_t , int ) {
return ::operator new(real_size);
}
static void deallocate(void* p, size_t , size_t , int ) {
::operator delete(p);
}
};
|
À§¿¡¼ ¸¸µç ChunkAllocator¿Í °°Àº ¹®¹ýÀ» »ç¿ëÇÏ´Â allocator, deallocator ÇÔ¼ö¸¦ °¡Áö°í ÀÖÀ¸¸ç ÇÏ´Â ÀÏÀº ´Ü¼øÈ÷ ::operator new¿Í ::operator delete¸¦ È£ÃâÇØÁÖ´Â °ÍÀÔ´Ï´Ù.
±×·³ ¾î¶»°Ô ÄÄÆÄÀÏ ½Ã°£¿¡ DefaultAllocator¸¦ ºÎ¸¦Áö ChunkAllocator¸¦ ºÎ¸¦Áö °áÁ¤ÇÒ ¼ö ÀÖÀ»±î¿ä?
size_helper
¿©±â¼ Àá½Ã, À§¿¡¼ ¾Ë¾Æº» ³»¿ëµéÀ» ±¸ÇöÇÏ·Á¸é »ç¿ëÀڷκÎÅÍ ÀԷ¹ÞÀº ÃÖ¼Ò°ª°ú ÃÖ´ë°ªÀ» °¡Áö°í ƯÁ¤ Å©±â°¡ ÃÖ´ë°ªÀ»
³Ñ´ÂÁö, ¶Ç´Â ÃÖ´ë°ªÀ» ³ÑÁö ¾Ê´Â´Ù¸é ¸î¹ø indexÀÇ poolÀ» »ç¿ëÇØ¾ß ÇÏ´ÂÁö, ±×¸®°í ±× poolÀÇ Å©±â´Â ¾ó¸¶ÀÎÁöµîÀ»
ÄÄÆÄÀÏ ½Ã°£¿¡ ¾Ë ¼ö ÀÖ´Â ¹æ¹ýÀÌ ÇÊ¿äÇÕ´Ï´Ù.
Áï, ÃÖ¼Ò°ª 32, ÃÖ´ë°ª 4096À» »ç¿ëÇÑ´Ù¸é ´ÙÀ½°ú °°ÀÌ ÀԷ°ª¿¡ ´ëÇÑ Ãâ·ÂÀÌ ³ª¿À´Â ¹æ¹ýÀÌ ÇÊ¿äÇÕ´Ï´Ù.
| ÀԷ°ª
| over_size
| index
| size
|
| 100
| false
| 2
| 128
|
| 300
| false
| 4
| 512
|
| 5000
| true
| x
| x
|
ÀÌ °ªµéÀ» ÄÄÆÄÀÏ ½Ã°£¿¡ ±¸Çϱâ À§ÇØ ¾Æ·¡¿Í °°Àº template meta functionÀ» ±¸ÇöÇÕ´Ï´Ù.
template <int SIZE, int N, int MAX_SIZE>
struct size_helper_impl
{
enum
{
size = (SIZE < N ? N : size_helper_impl<SIZE, 2 * N, MAX_SIZE>::size),
index = (SIZE < N ? 0 : 1 + size_helper_impl<SIZE, 2 * N, MAX_SIZE>::index),
over_size = (SIZE > MAX_SIZE ? 1 : 0)
};
};
template <int SIZE, int MAX_SIZE>
struct size_helper_impl<SIZE, MAX_SIZE, MAX_SIZE>
{
enum
{
size = MAX_SIZE,
index = 0,
over_size = 1
};
};
|
À§ÀÇ Äڵ忡¼ NÀº ÃÖÃÊ ÀԷ½ÿ£ MIN_SIZE°¡ ÀԷµǸç ÀÌ °ªÀÌ MAX_SIZE°¡ µÉ¶§±îÁö 2¸¦ °öÇÕ´Ï´Ù. µÎ¹øÂ°
template specializationÀº NÀÌ MAX_SIZE°¡ µÇ¸é loop¸¦ ¸ØÃß±â À§ÇØ ÇÊ¿äÇÕ´Ï´Ù. ÀÌ·± ¹æ¹ýÀº óÀ½
º¸±â¿£ Á¶±Ý º¹ÀâÇØ º¸ÀÌÁö¸¸ Çϳª¾¿ ¼ÕÀ¸·Î µû¶ó°¡´Ù º¸¸é ½±°Ô ÀÌÇØµË´Ï´Ù.
¿©±â¼ »ç¿ëÀÚ¿¡ ÀÇÇØ ÀÔ·ÂµÈ MIN_SIZE¿Í MAX_SIZE´Â ChunkAllocator¿¡¼ ¾Ë ¼ö ÀÖÀ¸¹Ç·Î ChunkAllocator¿¡ ´ÙÀ½°ú °°ÀÌ size_helper¸¦ size_helper_implÀ» »ç¿ëÇÏ¿© Á¤ÀÇÇÕ´Ï´Ù.
template <
int MIN_SIZE,
int MAX_SIZE,
int OBJS_IN_A_BLOCK,
class LockModel
>
class ChunkAllocator
{
public:
...
template <int SIZE>
struct size_helper
{
typedef detail::size_helper_impl<SIZE, MIN_SIZE, MAX_SIZE> type;
};
...
|
´Ù½Ã MemPoolSize ±¸Çö
±×·³ À§¿¡¼ ¸¸µç size_helper¸¦ »ç¿ëÇÏ¿© MemPoolSize¸¦ ±¸ÇöÇØº¸µµ·Ï ÇϰڽÀ´Ï´Ù. ¸ÕÀú
size_helperÀÇ over_size°¡ trueÀÎ °æ¿ì, Áï »ç¿ëÇÒ Å¬·¡½ºÀÇ Å©±â°¡ MAX_SIZEº¸´Ù Ŭ °æ¿ì¿¡´Â
DefaultAllocator, ÀÛÀ» °æ¿ì¿¡´Â ChunkAllocator¸¦ »ç¿ëÇØ¾ß ÇϹǷΠ´ÙÀ½°ú °°Àº
type_selector°¡ ÇÊ¿äÇÕ´Ï´Ù.
template <bool flag, class T1, class T2>
struct type_selector
{
typedef T1 type;
};
template <class T1, class T2>
struct type_selector<false, T1, T2>
{
typedef T2 type;
};
|
À§¿Í °°ÀÌ type_selector¸¦ ¸¸µé¾î¼ »ç¿ëÇØµµ ±×¸® ¾î·ÆÁö´Â ¾ÊÀ¸³ª À§¿Í ¶È°°Àº ÀÛ¾÷À» Çϴ ŸÀÔÀÌ À̹Ì
boost::mpl¿¡ if_c¶ó´Â À̸§À¸·Î Á¤ÀǵǾî ÀÖ½À´Ï´Ù µû¶ó¼ ¿©±â¼´Â boost::mpl::if_c ¸¦ »ç¿ëÇÕ´Ï´Ù.
static void* operator new (size_t size) {
typedef typename ChunkAllocator::size_helper<sizeof(T)>::type size_helper;
typedef typename boost::mpl::if_c<
size_helper::over_size,
detail::DefaultAllocator,
ChunkAllocator
>::type Allocator;
return Allocator::allocate(size,
size_helper::size,
size_helper::index);
}
static void operator delete (void* p, size_t size) {
if (p == 0) return;
typedef typename ChunkAllocator::size_helper<sizeof(T)>::type size_helper;
typedef typename boost::mpl::if_c<
size_helper::over_size,
detail::DefaultAllocator,
ChunkAllocator
>::type Allocator;
Allocator::deallocate(p,
size,
size_helper::size,
size_helper::index);
}
|
»ç¿ë ¿¹Á¦
°£´ÜÇÑ »ç¿ë ¿¹Á¦µéÀ» »ìÆì º¸°Ú½À´Ï´Ù. ¾Æ·¡¿Í °°ÀÌ ³×°³ÀÇ Å¬·¡½º¸¦ Á¤ÀÇÇÕ´Ï´Ù.
struct A : MemPoolSize<A>
{
char buf[10];
};
struct B : MemPoolSize< B>
{
char buf[30];
};
struct C : MemPoolSize<C>
{
char buf[200];
};
struct D : MemPoolSize<D>
{
char buf[5000];
};
|
new A;
new B;
new C;
new D;
A::get_impl()->print();
|
±×¸®°í À§ÀÇ Äڵ带 ½ÇÇà½ÃŰ¸é ´ÙÀ½°ú °°Àº °á°ú¸¦ ¾òÀ» ¼ö ÀÖ½À´Ï´Ù.
--------- --------- ---------
ChunkSize ObjSize PoolSize
--------- --------- ---------
32 2 50
64 0 0
128 0 0
256 1 50
512 0 0
1024 0 0
2048 0 0
4096 0 0
--------- --------- ---------
|
¹°·Ð A, B´Â 0¹øÂ° index¿¡ C´Â 3¹øÂ° index¿¡ ±×¸®°í D´Â ChunkAllocator°¡ ¾Æ´Ñ
DefaultAllcator·Î »ý¼ºµÇ¾î À§ÀÇ °á°ú¿¡ Æ÷ÇÔµÇÁö ¾Ê¾ÒÀ½À» ¾Ë ¼ö ÀÖ½À´Ï´Ù. ¿©±â¼ get_impl() ÇÔ¼ö´Â
µð¹ö±ëÀ» ½±°Ô Çϱâ À§ÇØ MemPoolSize¿¡¼ Á¦°øÇÏ´Â ÇÔ¼öÀÔ´Ï´Ù. ³»ºÎÀûÀ¸·Î ±× Ŭ·¡½º°¡ »ç¿ëÇϰí ÀÖ´Â
ChunkAllocatorImpl Æ÷ÀÎÅ͸¦ ¸®ÅÏÇÕ´Ï´Ù. µû¶ó¼ A::get_impl()À̳ª B::get_impl(),
C::get_impl()Àº ¸ðµÎ °°Àº Æ÷ÀÎÅ͸¦ ¸®ÅÏÇÕ´Ï´Ù.
¹°·Ð DefaultAllocator¿¡´Â get_impl()ÀÌ Á¤ÀǵǾî ÀÖÁö ¾ÊÀ¸¹Ç·Î D::get_impl() ÇÔ¼ö¸¦ È£ÃâÇϸé ÄÄÆÄÀÏ ¿¡·¯°¡ ¹ß»ýÇÕ´Ï´Ù.
¸¶¹«¸®
À̹ø¿¡ ¸¸µé¾î º» MemPoolSize´Â Modern C++ DesignÀÇ SmallObj¿Í ±× ±¸Á¶´Â À¯»çÇϳª ±¸Çö
¹æÇâÀº ¸¹ÀÌ ´Ù¸¨´Ï´Ù. °¡Àå ´Ù¸¥ Á¡Àº SmallObj´Â »ç¿ëÀÚÀÇ ÆíÀ̼ºÀ» À§ÇØ runtime overhead¸¦ °¨¼öÇÏ¿´°í
MemPoolSize´Â »ç¿ëÀÇ ÆíÀ̼ºÀ» Á¶±Ý ³·Ãç runtime overhead¸¦ ¿ÏÀüÈ÷ Á¦°ÅÇß´Ù´Â Á¡ÀÔ´Ï´Ù.
¿©±â¼ ÆíÀ̼ºÀ» ³·Ãè´Ù´Â Àǹ̴ MemPoolSize Ŭ·¡½º´Â Ç×»ó leaf Ŭ·¡½º¿¡¼ »ç¿ëµÇ¾î¾ß ÇÑ´Ù´Â
°ÍÀÔ´Ï´Ù. SmallObj´Â Á¦ÀÏ »óÀ§ÀÇ base Ŭ·¡½º¿¡¼ »ó¼Ó¹Þ¾Æ ³õÀ¸¸é ±× ÀÌÇÏÀÇ Å¬·¡½º¿¡¼´Â ½Å°æ¾²Áö ¾Ê¾Æµµ µÇÁö¸¸
MemPoolSize´Â Ç×»ó leaf Ŭ·¡½º¿¡¼ »ó¼ÓÀ» ¹Þ¾Æ »ç¿ëÇØ¾ß ÇÕ´Ï´Ù. ¸¸¾à ±×·¸Áö ¾ÊÀº °æ¿ì allocate¿¡¼
assertion ¿¡·¯¸¦ ¹ß»ýÇÏ°Ô µË´Ï´Ù. (½ÇÁ¦ Ŭ·¡½ºÀÇ Å©±â°¡ poolÀÇ Å©±âº¸´Ù Å« °æ¿ìÀÔ´Ï´Ù.)
¸¶Áö¸·À¸·Î ÇöÀç ±¸ÇöµÈ MemPoolSize´Â »ç¿ëÇϰíÀÚ Çϴ ȯ°æ¿¡ µû¶ó ´Ù¾çÇÑ °³¼± »çÇ×ÀÌ ÀÖÀ» ¼ö ÀÖ½À´Ï´Ù.
¿¹¸¦ µé¾î ÇöÀç 2ÀÇ ÀÚ½ÂÀ¸·Î »ý¼ºµÇ´Â pool µéÀ» 2ÀÇ °öÀ¸·Î »ý¼ºÇÑ´Ù´ø°¡ ÇÏ´Â ½ÄÀÔ´Ï´Ù. (Áï, 32, 64, 128,
... ÀÌ·± ½ÄÀ¸·Î »ý¼ºµÇ´Â °ÍÀÌ ¾Æ´Ï¶ó 32, 64, 96, 128, ... À¸·Î »ý¼º.) ¿¬½À»ï¾Æ ÇØº¸½Ã¸é ÁÁÀ» °Í
°°½À´Ï´Ù.
±×·³ À̰ÍÀ¸·Î MemPool °Á¸¦ ¸¶Ä¡°Ú½À´Ï´Ù. ³¡±îÁö ÀоîÁּż °¨»çÇÕ´Ï´Ù.
|