Согласно нескольким источникам, в том числе Wikipedia, два наиболее часто используемых способов реализации двоичного дерева являются:Как реализовать дружественное к кэшу динамическое двоичное дерево?
- Узлы и указатели (или ссылки), где каждый узел явно держит своих детей.
- Array где положение дочерних узлов задано неявно по индексу его родителя.
Второй, очевидно, выше с точки зрения использования памяти и местности ссылкой. Однако это может привести к проблемам, если вы хотите разрешить вставки и удаление с дерева таким образом, чтобы можно было оставить дерево неуравновешенный. Это связано с тем, что использование памяти в этом проекте является экспоненциальной функцией глубины дерева.
Предположим, что вы хотите поддерживать такие вставки и удаления. Как вы можете реализовать дерево таким образом, чтобы обход дерева эффективно использовал кэширование CPU.
Я думал о создании пула объектов для узлов и распределении их в массиве. Таким образом, узлы будут близки друг к другу -> следовательно, хорошая локальность ссылки.
Но если размер узла совпадает с размером строки кэша, имеет ли это смысл?
Если у вас есть размер линии L1, равный 64 байтам, и вы получаете доступ к первому члену std::vector<std::uint8_t>(64)
, вы, возможно, будете иметь все содержимое вектора в вашем кеше L1. Это означает, что вы можете получить доступ к любому элементу очень быстро. Но что, если размер элемента совпадает с размером строки кеша? Поскольку строка кэша likely not to be very different для кэшей L1, L2 и L3, похоже, здесь не может быть полезной локальность ссылок. Я ошибаюсь? Что еще можно сделать?
«Второй, очевидно, превосходит практически любой смысл». Помимо кеширования - почему? –
@NeilButterworth Это была глупость писать от меня. Я попытался уточнить это. Не стесняйтесь редактировать, если у вас есть другие предложения. –
Возможно, std :: deque, а не std :: vector (или массив). _ «типичные реализации используют последовательность индивидуально распределенных массивов фиксированного размера». _ из http://en.cppreference.com/w/cpp/container/deque. Также просмотрите производительность std :: vector (попытайтесь найти это ссылка) - Случайные вставки/удаления с использованием std :: vector vs std :: list, вектор лучше работает до 100,00 элементов (приблизительный) –