2013-05-24 11 views
8

C++ 11 tipi özelliklerden yararlanmak için havuzlanmış sabit blok bellek ayırıcımızı yükseltmeyi deniyorum.Global yeni operatör, ayrılan nesnenin tür özelliklerine göre geçersiz kılınabilir mi?

Şu anda, örn Birçok durumda

void* operator new (std::size_t size) 
{ // if-cascade just for simplest possible example 
    if (size <= 64) { return g_BlockPool64.Allocate(); } 
    else if (size <= 256) { return g_BlockPool256.Allocate(); } 
    // etc .. else assume arguendo that we know the following will work properly 
    else return malloc(size); 
} 

daha ileri eğer performansını iyileştirebilecek geleneksel yolla the global new operator geçersiz kılarak yerde doğru havuza sevk edilecek herhangi bir nesnenin herhangi tahsisini zorlamak mümkündür Nesneler, is_trivially_destructible gibi tür özelliklerine bağlı olarak farklı havuzlara gönderilebilir. Sadece istenen bir boyutta değil, tahsis edilen türden haberdar olan templatize küresel bir operatör yapmak mümkün mü?

template<class T> 
void *operator new(size_t size) 
{ 
    if (size < 64) 
    { return std::is_trivially_destructible<T>::value ? 
      g_BlockPool64_A.Allocate() : 
      g_BlockPool64_B.Allocate(); } // etc 
} 

burada çalışmaz her sınıfta üyesi yeni operatörünü geçersiz kılma eşdeğer şey; Her yerde herhangi bir tahsis için otomatik olarak çalışmak için buna gerçekten ihtiyacımız var.

Foo *p = new (mempool<Foo>) Foo(); 

gibi görünmek için her alloc gerektiren çok hantal ve insanlar onu kullanmayı unutacak: Yerleştirme yeni ya çalışmaz.

+1

Temiz bir fikir. Her ne kadar önemsiz bir şekilde yıkıcı olunur bellek yöneticisine nasıl yardımcı olur? Müdür inşaat veya yıkım hakkında umurunda değil. – GManNickG

+0

@GManNickG Tüm önemsiz derecede yıkıcı nesneler aynı havuza girerse, sadece bellek sayfasını unmatarak ve herhangi bir yıkıcıyı arayarak onları maskeleyerek ayırabiliriz. Milyonlarca tahsisat yerine bir işletim sistemi çağrısı. Bir seviye yığın için tüm tahsisler bir bloğa gittiğinde ve sadece o alanı terk ederken şeyi denize atabildiğinizde kullanışlıdır. İnsanların yaşamları boyunca bu bloğa işaretçi tutmasını engellemek için zaten başka mekanizmalar var. – Crashworks

+0

Hayır. Ayrıca, 'dönüş :: yeni (boyut);' sonsuz yineleme. – aschepler

cevap

3

Kısa cevap no. Hiç kullanılmayan Fonksiyonunuzda sonuçlanacaktır bu imzaların gelen

void* operator new(std::size_t); 
void* operator new[](std::size_t); 
void operator delete(void*); 
void operator delete[](void*); 

En sapmalar: tahsisi/deallocation işlevleri aşağıdaki imzaları var. Tipik bir uygulamada temel olarak varsayılan uygulamaların linker seviyesinde değiştirilmesidir - yani, mevcut fonksiyonun bazı belirli mandallı isimleri vardır. Aynı sonuca yönlendiren bir ada sahip bir işlev sağlıyorsanız, bunun yerine bağlantı verilir. İşiniz aynı ada sahip değilse, bağlantı kurulamaz.

Önerdiğiniz gibi bir şablon bazı durumlarda kullanılmış olabilir, ancak böyle ise tanımlanmamış davranışlara yol açacaktır. Başlıklarınızı nasıl düzenlediğinize bağlı olarak (örneğin), şablonunuzun varsayılan işlevlerle karışmasını sağlayan bir kodla sonuçlanabilirsiniz. Bu noktada, en iyi ihtimalle umduğunuz kadar çabuk ve hızlı bir şekilde çökecektir.

İlgili konular