У меня около 18 миллионов элементов в массиве, которые инициализированы и готовы к использованию простым менеджером по имени ElementManager
(позднее это число увеличится до чуть более миллиарда в последующих итерациях программы). Класс A
, который должен использовать элементы, связывается с ElementManager
, который возвращает следующий доступный элемент для потребления. Этот элемент в настоящее время используется и не может быть повторно использован до повторного использования, что может случаться часто. Класс A
является одновременным, то есть он может запросить ElementManager
о доступном элементе в нескольких потоках. Элементами в этом случае является объект, который хранит три вершины, чтобы сделать треугольник.
В настоящее время ElementManager
использует Intel TBB concurrent_bounded_queue с именем mAllAvailableElements
. Существует также другой контейнер (TBB concurrent_vector), который содержит все элементы независимо от того, доступны ли они для использования или нет, который называется mAllElements
. Класс A
запрашивает следующий доступный элемент, менеджер пытается извлечь следующий доступный элемент из очереди. Выскочивший элемент сейчас используется.
Теперь, когда класс A
сделал то, что должен, управление передается классу B
, который теперь должен перебирать все элементы in use
и создавать сетки (чтобы использовать преимущества параллелизма , массив разбивается на несколько меньших массивов для создания подсетей, которые масштабируются в зависимости от количества доступных потоков - причина этого заключается в том, что создание сетки должно выполняться последовательно) . Для этого я в настоящее время перебираю контейнер mAllElements
(это также одновременно) и собираю любой элемент, который используется . Элементы, как упоминалось выше, содержат многоугольную информацию для создания сеток. Итерация в этом случае занимает много времени, так как она должна проверять каждый элемент и запрашивать, используется ли он или нет, потому что, если он не используется , то он не должен быть частью сетки.
Теперь представьте, что только 1 миллион из возможных 18 миллионов элементов был в использовании (но более 5-6 миллионов было переработано). Что еще хуже, из-за постоянных обновлений только части сетки (что происходит одновременно) означает, что используемые элементы фрагментированы по всему контейнеру mAllElements
.
Я думал об этом уже довольно давно, и одним из ошибочных решений, которое я предложил, было создание еще одной очереди элементов с именем mElementsInUse
, которая также является concurrent_queue
. Я могу нажать на любой элемент, который сейчас используется . Проблема с этим подходом состоит в том, что, поскольку это очередь, любой элемент в этой очереди может быть переработан в любое время (обновление в части сетки) и объявлен не используется , и так как я могу только выдавать передний элемент, этот подход не удается. Единственный другой подход, о котором я могу подумать, - это дефрагментировать concurrent_vector mAllElements
время от времени, когда не выполняется никаких операций.
Я думаю, что мой подход к этой проблеме неправильный, и поэтому мой пост здесь. Надеюсь, я объяснил проблему достаточно подробно. Это похоже на обычную проблему управления памятью, но я не могу найти какие-либо условия поиска для ее поиска.