Сократить переключение контекста между потоками с одинаковым приоритетом

Я пишу приложение, которое использует стороннюю библиотеку для выполнения сложных вычислений.

Эта библиотека реализует внутренний параллелизм и порождает заданные числовые потоки. Я хочу запустить несколько экземпляров этой библиотеки (с динамическим счетом) и, следовательно, в конечном итоге с чрезмерной подпиской ЦП.

Есть ли способ, которым я могу увеличить «квант времени» всех потоков в процессе, например: все потоки с нормальным приоритетом редко переключают контекст (yield), если они явно не получены через, например, семафоры?

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

РЕДАКТИРОВАТЬ:

Один из сложных способов сделать это — выполнить планирование потоков вручную.

  1. Перечислите все потоки с определенным приоритетом (например, обычный).
  2. Приостановить все из них.
  3. Создайте цикл, который возобновляет / приостанавливает потоки каждый раз, например. 40 мс и гарантирует, что не будет запущено больше потоков, чем текущее число процессоров.

Есть ли серьезные недостатки у этого подхода? Не уверен, что накладные расходы на возобновление / приостановку потока?

6

Решение

Там нет ничего особенного, что вам нужно сделать. Любой достойный планировщик не позволит принудительным переключателям контекста потреблять значительную долю ресурсов ЦП. Любая операционная система, у которой нет достойного планировщика, не должна использоваться.

Повышение производительности при превышении подписки на процессор не стоимость принудительного переключения контекста. Зачем? Потому что планировщик может просто избежать этого. Планировщик выполняет принудительное переключение контекста только тогда, когда это имеет преимущество. Расходы на производительность:

  1. Завершение работы может занять больше времени, поскольку на других работах будет больше работы между началом работы и ее завершением.

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

  3. Большее количество потоков обычно означает большее количество конфликтов (например, когда выделяется память), что может означать более принудительное переключение контекста, когда поток должен быть отключен, поскольку он не может продвигаться вперед.

Вы хотите попытаться изменить поведение планировщика, только когда знаете что-то существенное, чего не знает планировщик. Здесь ничего подобного не происходит. Поэтому поведение по умолчанию — то, что вы хотите.

4

Другие решения

Есть ли серьезные недостатки у этого подхода? Не уверен, что накладные расходы
возобновить / приостановить поток?

да,возобновить / приостановить поток — очень и очень опасное действие, выполняемое в пользовательский режим программы. Так что не стоит его использовать (почти никогда). Более того, мы не должны использовать эти концепции для достижения того, что любой современный планировщик делает для нас. Это тоже упоминается в другом посте этого вопроса.

Вышеуказанное применимо для любой операционной системы, но из SO post tag мне кажется, что его попросили Майкрософт Виндоус основанная система. Теперь, если мы читаем о SuspendThread () из MSDN мы получаем следующее:

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

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

2