Эффективно выделяя много недолгих маленьких объектов

У меня есть маленький класс (16 байтов в системе на 32 бита), который я должен динамично выделить. В большинстве случаев время жизни любого приведенного примера очень коротко. Некоторые экземпляры могут также быть переданы через границы потока.

Сделав некоторое профилирование, я нашел, что моя программа, кажется, проводит больше времени, выделяя и освобождая вещи, чем это на самом деле тратит использование их так, я хочу заменить новое значение по умолчанию и удалить с чем-то что немного более эффективный.

Для большого объекта (соединения дб, как это происходит, которые являются дорогими создать, а не выделить), я уже использую систему объединения, однако который включает список для хранения "свободных" объектов и также взаимного исключения для потокобезопасности. Между взаимным исключением и списком это на самом деле работает хуже, чем с основным новым/удал для маленьких объектов.

Я нашел много маленьких объектных средств выделения на Google, однако они, кажется, используют глобальный/статичный пул, который не используется ориентированным на многопотоковое исполнение способом, делая их неподходящими для моего использования: (

Что другие опции я получил для эффективного управления памятью таких маленьких объектов?

10
задан Fire Lancer 28 January 2010 в 18:05
поделиться

3 ответа

Может быть, попробуйте использовать Google TCMALLOC ? Он оптимизирован для быстрого распределения / Deallocation в резьбовой программе и имеет низкий накладные расходы для небольших объектов.

1
ответ дан 4 December 2019 в 04:36
поделиться

Вы можете убедиться, что вы используете низкому фрагментации . Он по умолчанию в Vista и позже, но я не думаю, что это так с более ранней ОС. Это может иметь большую разницу в скорости распределения для небольших объектов.

0
ответ дан 4 December 2019 в 04:36
поделиться

У меня достаточно тяжелое программирование в пути на ноутбуке (читать: не нетбук) просто потому, что у меня есть только один экран. Вы говорите мне, что кто-то рассмотрел бы программирование на этом использовании виртуальной клавиатуры, которая поднимает половину космоса экрана?

iCantBelieveYouAskedThis

-121--1465621-

Это связано с включением опции 'esckeys' (следствием несовместимого , как я только что обнаружил). При нажатии ^ [ O происходит небольшая задержка, так как выясняется, используете ли вы клавишу со стрелкой/функцией или вы просто подразумевали эти две клавиши в последовательности.

Одним из решений является отключение этой опции и отказ от клавиш со стрелками в режиме вставки.
Другое - установить 'timeoutlen' на что-то меньшее, чем 1000, может быть, 100 (но будьте осторожны при медленных соединениях).
Другим способом является использование ^ C вместо ^ [ для выхода из режима вставки.

-121--855463-

Некоторые экземпляры также могут быть пропущены через границы потоков

Только «некоторые»? Так что, возможно, вы можете позволить себе доплатить за них, если это удешевит те, которые не проходят к другим нитям. Есть несколько способов добраться до одного распределителя на поток и избежать необходимости блокировки при выделении или освобождении в потоке, которому принадлежит распределитель. Я не знаю, что может быть возможно в вашей программе:

  • Копировать вещи через границу потока, а не передавать их.

  • Если они передаются в другой поток по какой-либо причине, то они передаются обратно в исходный поток для освобождения. Это не обязательно должно происходить очень часто, вы можете поставить в очередь несколько в принимающем потоке и передать их все обратно в сообщение позже. Это предполагает, конечно, что нить, которая владеет распределителем, будет держаться вокруг.

  • Наличие двух свободных списков для каждого распределителя: одного синхронизированного (к которому добавляются объекты при их освобождении из другого потока) и одного несинхронизированного. Только если несинхронизированный список пуст, и вы выделяете (и, следовательно, в потоке, который владеет распределителем), вам нужно заблокировать синхронизированный список свободных и переместить все его текущее содержимое в несинхронизированный список. Если объекты, передаваемые другим потокам, редки, это в основном устраняет коллизию на мьютексе и массово уменьшает количество раз, когда он вообще принимается.

  • Если все вышеперечисленные ошибки, наличие одного распределителя на поток может все же позволить вам избавиться от мьютекса и использовать свободную от блокировки очередь для свободного списка (освобождение нескольких записывающих устройств, выделение одного считывающего устройства), что может немного улучшить производительность. Реализация очереди без блокировки зависит от платформы.

Делает ли ваше приложение шаг назад, часто попадает в состояние, в котором вы знаете, что все ячейки, выделенные после определенного пункта (возможно, немного в прошлом), больше не используются? Если это так, и если предположить, что разрушитель ваших маленьких объектов не делает ничего жутко срочного, то не утруждайте себя освобождением клеток -в «определенный пункт» создайте новый распределитель и отметьте старый как больше не используемый для новых распределений. Когда вы «попали в состояние», освободите весь распределитель и его базовый буфер. Если «определенная точка» и «состояние» одновременны, тем проще - достаточно сбросить распределитель.

1
ответ дан 4 December 2019 в 04:36
поделиться
Другие вопросы по тегам:

Похожие вопросы: