Ненужная блокировка в STL?(Visual C ++ Express) - PullRequest
4 голосов
/ 24 октября 2010

Я пытаюсь построить алгоритм искусственного интеллекта Tetris, который может масштабироваться на несколько ядер.

В моих тестах оказалось, что использование нескольких потоков медленнее, чем использование одного потока.

После некоторых исследований я обнаружил, что мои темы проводят большую часть своего времени в ожидании _Lockit _Lock(_LOCK_DEBUG). Вот скриншот .

Как видите, блокировка применяется к локальной переменной , которая в любом случае не требует блокировки!

Мои вопросы:

  • Почему STL блокирует этот вектор?
  • Как я могу сделать мою программу быстрее? (Использовать массивы?)

Обновление

Я снял блокировку, установив следующие параметры командной строки в моих проектах Visual Studio:

/D "_HAS_ITERATOR_DEBUGGING=0" /D "_SECURE_SCL=0"

Важно применить это ко всем проектам в файле решения, иначе во время выполнения возникнут ошибки (конфликтующие итераторы и т. Д.).

Вторая вещь, которую я изменил, меняла std::vector<bool> на std::vector<char>. Я не знал, что std::vector<bool> было так медленно.

1 Ответ

4 голосов
/ 24 октября 2010

Если вы проводите время в LOCK_DEBUG, то вы используете итераторы отладки.Все эти итераторы отслеживают свои позиции и родительские контейнеры и обнаруживают несколько случаев неопределенного поведения для вас.Однако они накладывают затраты времени выполнения.

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

Любая другая блокировка фактически потребуется для правильной работы - когда вы читаете из вектора,вы должны убедиться, что никто не записывает в этот вектор одновременно (по крайней мере, чтобы получить ожидаемую безопасность потоков в большинстве реализаций STL, а именно то, что разные читатели безопасны, даже если несколько писателей нет).Для этого требуется блокировка.

Также рассмотрите возможность не использовать vector<bool> (используйте вместо этого deque<bool> или vector<char> или vector<int>), так как обычно требуется больше накладных расходов на многопоточность, потому что он хранит псевдо-boolsв отдельных битах.Это позволяет ему поместиться больше в меньшем пространстве, но, к сожалению, означает, что чтение и запись в контейнер больше не являются атомарными, что может потребовать большей блокировки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...