Используется ли подсказка выделения?
Я читал, почему нет функции перераспределения в C++ распределителях? и возможно ли создать массив в куче во время выполнения, а затем выделять больше места при необходимости?, в котором четко указано, что перераспределение динамического массива объектов невозможно.
Тем не менее, в Стандартной библиотеке C++, автор Josuttis, в ней указывается распределитель, allocator
, имеет функцию allocate
со следующим синтаксисом
pointer allocator::allocate(size_type num, allocator<void>::pointer hint = 0)
где hint
имеет значение, определяемое реализацией, которое может использоваться для повышения производительности.
Есть ли реализации, которые используют это в своих интересах?
3 ответа
Я получил значительные преимущества в производительности за время итерации для небольших скалярных типов в моем контейнере plf:: colony C++, используя подсказки с std:: allocator в Visual Studio 2010-2013 (скорость итерации увеличилась на ~21%), и значительно меньшие ускорения в GCC 5.1. Так что можно с уверенностью сказать, что с этими компиляторами и std:: allocator это имеет значение. Но разница будет зависеть от компилятора. Мне не известно соотношение игнорирующих подсказки распределителей, наблюдающих за подсказками.
Я не уверен насчет конкретных реализаций, но учтите, что распределителю не разрешено возвращать значение указателя подсказки до его передачи deallocate
, Так что это не может быть использовано в качестве примитивной операции для формирования reallocate
,
Стандарт говорит, что подсказка должна быть возвращена предыдущим вызовом allocate
, В нем говорится "Использование [подсказка] не определено, но оно предназначено для помощи населению". Поэтому, если вы выделяете и освобождаете последовательность блоков одинакового размера в одном потоке, вы можете передать ранее освобожденное значение, чтобы избежать конфликта между кешами микропроцессора.
В противном случае, когда CPU B видит, что вы используете адреса памяти, все еще находящиеся в кэше CPU A (даже эта память содержит объекты, которые были уничтожены в соответствии с C++), он должен переслать ненужные данные по шине. Лучше позволить каждому ЦПУ A и B повторно использовать свои собственные соответствующие кэшированные адреса.
C++11 состояний, в 20.6.9.1 членов распределителя:
4 - [ Примечание: в функции-члене контейнера адрес соседнего элемента часто является хорошим выбором для передачи
hint
аргумент. - конец примечания ]
[...]
6 - [...] Использованиеhint
не определено, но предназначено как помощь населению, если реализация того пожелает.
Выделение новых элементов рядом или рядом с существующими элементами в памяти может повысить производительность, улучшая локальность; поскольку они обычно кэшируются вместе, соседние элементы будут стремиться перемещаться вместе вверх по иерархии памяти и не будут выселять друг друга.