Я написал некоторый код, который предоставляет пул вспомогательных потоков, которые мое (в основном последовательное) приложение может вызывать, когда у него есть задача, которая выиграет от распараллеливания.Это работает так:
Только один раз создайте пул потоков, равный (#cores на машине - 1).
Настройкацикл ожидания для них, чтобы они блокировали «занятую» критическую секцию, в настоящее время удерживаемую главным потоком, причем каждый поток имеет свою собственную секцию.(то есть в Windows EnterCriticalSection)
Когда запрашивается помощь, выполните настройку в главном потоке, который затем освобождает "занятые" критические секции (в Windows LeaveCriticalSection).
Затем мастер и отобранные дети отрабатывают до тех пор, пока не закончат, а мастер ждет, пока дети закончат.Вторая критическая секция для каждого потока, использующая ту же логику главного / подчиненного, обрабатывает процесс «ожидания завершения».
Все это прекрасно работает как в Linux, так и в Windows, ина самом деле, кажется, дает значительное улучшение производительности по сравнению с OpenMP, а также гораздо проще в использовании.Однако меня озадачивает одна вещь: мой профилировщик (я использую Intel VTune Amplifier) показывает значительное время вращения, когда я оставляю критическую секцию, т.е. RtlLeaveCriticalSection в Windows.
Почему?Разумеется, выход из критической секции - это необслуживаемая операция?
Что еще я могу с этим поделать?Я попытался поиграть с счетчиком спин-блокировок, но хотя я могу сократить время отжима, это также сокращает время до того, как потоки, ожидающие в секции, перейдут в спящий режим, поэтому я использую более истекшее время.