2010-04-17 2 views
8

В настоящее время я выделяю свою память для массивов с использованием MS_malloc. Я выравниваю память, так как я занимаюсь математикой с большой нагрузкой, и векторизация использует преимущество выравнивания. Мне было интересно, знает ли кто-нибудь, как перегружать нового оператора, чтобы сделать то же самое, поскольку я чувствую себя грязным malloc'ing всюду (и в конечном итоге хотел бы также скомпилировать на Linux)? Спасибо за любую помощьвозвращает выровненную память с новым?

ответ

10

Прежде всего, важно отметить, что new и delete могут быть перегружены либо глобально, либо только для одного класса. Оба случая показаны в this article. Также важно отметить, что если вы перегрузите new, вы почти наверняка также захотите перегрузить delete.

Есть несколько важных замечаний о operator new и operator delete:

  1. Стандарт C++ требует, чтобы действующий указатель возвращается, даже если размер ей передается 0.
  2. Там также operator new[] и operator delete[], поэтому не забывайте перегружать их.
  3. Производные классы наследуют operator new и его братьев, поэтому не забудьте их переопределить.

В Эффективное C++, пункт 8, Скотт Мейерс включает некоторые примеры pseudocodish:

void * operator new(size_t size)  // your operator new might 
{          // take additional params 
    if (size == 0) {      // handle 0-byte requests 
    size = 1;       // by treating them as 
    }          // 1-byte requests 
    while (1) { 
    attempt to allocate size bytes; 
    if (the allocation was successful) 
     return (a pointer to the memory); 

    // allocation was unsuccessful; find out what the 
    // current error-handling function is (see Item 7) 
    new_handler globalHandler = set_new_handler(0); 
    set_new_handler(globalHandler); 

    if (globalHandler) (*globalHandler)(); 
    else throw std::bad_alloc(); 
    } 
} 


void operator delete(void *rawMemory) 
{ 
    if (rawMemory == 0) return; // do nothing if the null 
           // pointer is being deleted 
    deallocate the memory pointed to by rawMemory; 
    return; 
} 

Для получения дополнительной информации, я бы определенно подобрать Эффективное использование C++.

+0

Итак, могу ли я просто поместить это в заголовок и ссылаться на этот заголовок во всех моих файлах? – Steve

+0

Ну, вы бы поместили определения в исходный файл, но да. – rlbond

+0

просто небольшая сноска: вы также можете определить 'operator new (size_t count, size_t alignment)', чтобы вы могли явно передать выравнивание в качестве аргумента для оператора new. Это можно было бы назвать «new (alignment) AlignedType» – user666412

2

new требуется для возврата pointer [...] suitably aligned so that it can be converted to a pointer of any complete object type (§3.7.3.1 стандарта).

FWIW, C++ 0x добавит alignof, в котором будет указано выравнивание, необходимое для определенного типа.

+3

К сожалению, по какой-то причине я никогда не понимал, компиляторы обычно не применяют это правило для 128-битных SIMD-типов. Я считаю, что они все еще «новые» с 8-байтовым выравниванием. – jalf

+0

@jalf: две причины: (1) чем больше выровненных распределений, тем выше накладные расходы на блок. Если вы сделаете много 17-байтных распределений, вы увидите разницу между их 16-юстировками и только их 4-ю выравнивание. (2) (специфичный для GNU), glibc делает меньше допущений для платформы, чем GCC, и не знает и не заботится о том, какой самый большой тип может поддерживать какой-то компилятор в системе. Но GCC «хочет» передать malloc прямо на glibc, а не добавить свой собственный механизм выравнивания, причем еще больше накладных расходов, чем malloc. Я где-то читал интересный публичный аргумент. –

+0

...наконец, компилятор мог бы в теории выбрать просто выравнивание вызовов на «новый SIMD_Type», избегая накладных расходов при всех распределениях более 15 байт. Но это все равно будет ошибкой, потому что если вы это сделаете, вам также следует выровнять вызовы с 'new char [sizeof (SIMD_Type)]'. Консенсус заключается в том, чтобы притворяться, что SIMD-типы не являются «правильными встроенными типами», это специальные вещи, которые должны быть выделены специально. –

Смежные вопросы