Наш многопоточный сервер имеет сотни потоков соединений, которые отвечают за обработку ввода-вывода и ответ на входящие запросы.
Есть еще один асинхронный поток, который время от времени выполняет относительно тяжелые задачи с большим количеством выделений (скажем, каждые несколько секунд).
После того, как я преобразовал этот поток в небольшой пул потоков (то есть эти задачи теперь выполняются из разных потоков каждый раз), наш сервер обычно использует одно и то же использование ЦП, но может внезапно достичь состояния, когда распределение между всеми операциями занимает гораздо больше времени, а общий ЦП использование сервера почти удваивается с 2 ядер до 3,7 ядер.
До сих пор моя основная теория заключается в том, что я каким-то образом изменяю схему доступа к библиотеке tcmalloc, и это вызывает случайные загрузки процессора. Что я должен посмотреть в статистике tcmalloc, чтобы подтвердить эту теорию? Может ли быть так, что один и тот же код, выполняемый сейчас из разных потоков (но не одновременно), заставляет tcmalloc выделять из центрального кэша больше, чем из кэша потоков?
Как предложили несколько комментаторов, ложная передача может быть проблемой. Поиск ложного обмена труден и плохо поддерживается текущими инструментами. Моя исследовательская группа опубликовала эти исследовательские работы по этой теме — как минимум, они обеспечивают отличное введение в проблему ложного обмена информацией и почему она так коварна.
Инструменты, соответствующие этим исследованиям, доступны на GitHub: шериф, хищник.
Хотя вы можете попытаться использовать один из этих инструментов, чтобы найти проблему, проще всего было бы дать копить попытка Hoard — это быстрая, масштабируемая замена malloc, конструкция которой снижает риск ложного совместного использования, вызванного распределителем. Если замена tcmalloc на Hoard не решит вашу проблему, то, возможно, имеет смысл поискать другие пути.