Несколько дней назад мне довелось посмотреть эту очень интересную презентацию от Stephan T. Lavavej, в которой упоминается оптимизация "Мы знаем, где вы живете" (извините за использование акроним в заголовке вопроса, SO предупредил меня, что вопрос может быть закрыт в противном случае), и этот красивый от Herb Sutter по машинной архитектуре.
Вкратце, оптимизация "Мы знаем, где вы живете" состоит в том, чтобы разместить контрольные счетчики в том же блоке памяти, что и объект, который make_shared
создает, что приводит к одному распределению памяти, а не к двум, и делает shared_ptr
более компактный.
После того, как я обобщил то, что я узнал из двух представленных выше презентаций, я начал задаваться вопросом, не может ли оптимизация WKWYL ухудшить производительность, если к shared_ptr
обращаются несколько потоков, работающих на разных ядрах.
Если контрольные счетчики близки к фактическому объекту в памяти, на самом деле они скорее всего будут выбраны в ту же строку кэша, что и сам объект. Это, в свою очередь, если бы я правильно узаконил, скорее всего, потоки будут замедляться при конкурировании за одну и ту же линию кэша, даже если они не нужны.
Предположим, что один для потоков требуется обновить счетчик ссылок несколько раз (например, при копировании shared_ptr
), а остальные просто нужны для доступа к заостренному объекту: разве это не замедлит выполнение потоков all, заставив их конкурировать за одну и ту же строку кэша?
Если пересчет жил где-то в памяти, я бы сказал, что утверждение будет менее вероятным..
Является ли это хорошим аргументом против использования make_shared()
в подобных случаях (если, конечно, он реализует WKWYL-оптимизацию)? Или есть ошибочность в моих рассуждениях?