конфликт потоков при динамическом выделении памяти - PullRequest
1 голос
/ 11 октября 2010

Я только что узнал, что на языке C * функция 1001 * связана с проблемой конфликта потоков при использовании в многопоточных приложениях.

В C ++ страдает ли operator new та же проблема?Если да, то какую технику я могу использовать, чтобы избежать этого, что звучит как большой штраф в производительности приложения?

Ответы [ 4 ]

2 голосов
/ 11 октября 2010

Эта «проблема» конфликта потоков действительно зависит от реализации. Некоторые реализации общего использования malloc изначально не были разработаны с учетом многопоточности. Но реализация malloc, предназначенная для многопоточных приложений, не должна страдать от конфликтов в нормальных условиях.

В качестве примера реализации malloc, разработанной с учетом многопоточности, посмотрите на jemalloc .

0 голосов
/ 11 октября 2010

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

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

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

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

0 голосов
/ 11 октября 2010

В C ++ оператор new страдает от той же проблемы?

Да, в большинстве реализаций это так.

Если вы уже находитесь в C ++, Threading Building Blocks - это библиотека шаблонов C ++, которая должна соответствовать вашим потребностям. Он имеет масштабируемые распределители, структуры данных, веб-сайт и многое другое ...

0 голосов
/ 11 октября 2010

В зависимости от реализации new, но, как правило, на основе malloc, да.Вот несколько вещей, которые вы можете сделать:

  • Используйте профилировщик для подсчета количества вызовов до malloc() (и, возможно, brk()) в секунду, убедитесь, что у вас есть проблема конкуренции с malloc(),
  • Попробуйте работать с параллельным распределителем памяти (т. Е. hoard )
  • Используйте стек, когда это возможно: не вызывайте new, когда вам это не нужно.Также помните, что небольшие копии обычно более удобны для кэша, чем указатели и данные, разделяемые между потоками.
...