Продуманное, динамическое управление нагрузкой на процессор - PullRequest
3 голосов
/ 11 октября 2011

Я пишу процессорную библиотеку обработки изображений. Чтобы наилучшим образом использовать доступный процессор, я могу определить общее количество ядер на моей машине и запустить мою библиотеку с таким количеством потоков. Когда моя библиотека выделяет один поток для каждого ядра, она работает оптимально, используя 100% доступного процессорного времени.

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

Итак, я хотел бы найти способ определить «справедливую долю» количества потоков, запускаемых при определенной загрузке. Например, если два экземпляра моего процесса выполняются на 8-ядерном компьютере, каждый из них будет работать с 4 потоками. Каждому из них нужен способ динамической адаптации числа потоков в соответствии с колебаниями нагрузки на машину.

Итак, мой вопрос:

  • Существует ли какая-либо функция ОС или сторонняя библиотека, которая позволяет моему процессу динамически адаптировать счетчик потоков, чтобы использовать свою долю ресурсов ЦП?

Я занимаюсь Windows, но также заинтересован в решениях, отличных от Windows.

Редактировать: чтобы было ясно, речь идет об оптимизации. Я пытаюсь достичь максимальной эффективности, используя оптимальное количество потоков, соответствующее моей справедливой доле ЦП.

Ответы [ 2 ]

1 голос
/ 12 октября 2011

На самом деле это не проблема многопоточности, а проблема одновременного выполнения многих программ.Это сложно для большинства операционных систем ПК, потому что это противоречит идее разделения времени.

Давайте предположим некоторый рабочий процесс.

Предположим, у нас есть 8 ядер и мы создаем 8 потоков для их подачи;хорошо это легкоДалее мы выбираем мониторинг загрузки ядра, чтобы подвести итог, сколько задач выполняется на определенном ядре;ну, это требует некоторых статистических допущений, например, в Linux вы можете получить график средней нагрузки за 1/5/15 минут, но это можно сделать.Статистическая диаграмма ясна, и теперь мы получаем график о том, сколько процессов с привязкой к процессору выполняется, скажем, наблюдая за другими процессами, интенсивно использующими три процессора.

Затем мы подошли к вопросу: мы должны сделать 3 избыточныхспящих потоков, но какие 3?

Обычно мы выбираем 3 потока произвольно, потому что планировщик автоматически организует остальные 8 потоков, связанных с процессором.В некоторых случаях мы явно переводим потоки на ядра с высокой нагрузкой в ​​спящий режим, назначаем другие потоки определенным ядрам с низкой нагрузкой и позволяем планировщику делать все остальное.Большинство политик планирования также пытаются «поддерживать кэш процессора горячим» , что означает, что они имеют тенденцию запрещать передачу потоков между ядрами.Мы разумно ожидаем, что наши ресурсоемкие потоки могут использовать основной кэш, поскольку другие процессы запланированы для 3 переполненных ядер.Все выглядит хорошо.

Однако это может привести к сбою в строго синхронизированных вычислениях.В этом сценарии нам нужно запустить наши 5 потоков одновременно.Одновременность здесь означает, что 5 потоков должны получить процессор и работать почти одновременно.Я не знаю, есть ли какой-нибудь планировщик на ПК, который мог бы сделать это для нас.В большинстве случаев низкой нагрузки все по-прежнему работает нормально, поскольку затраты на ожидание одновременности тривиальны.Но когда нагрузка на ядро ​​высока и даже 1 из 5 наших потоков нарушен, иногда мы обнаруживаем, что тратим много жизненных циклов на ожидание.

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

1 голос
/ 11 октября 2011

На мой взгляд, приложение не должно решать, сколько потоков порождать.Это информация, которую звонящий должен знать.В linux широко используется параметр "-j" или "--jobs" (по умолчанию: 1).

Как насчет установки priority задач обработки.Таким образом, если вызывающий знает, что обработка является критически важной, он может увеличить prio (со знанием того, что может заблокировать (целую) систему).Ваша библиотека обработки никогда не узнает, насколько важной будет обработка этого изображения.Если вызывающему абоненту все равно, то используется низкое значение по умолчанию, которое не должно влиять на остальную часть системы.Если это произойдет, вы должны посмотреть, что именно блокирует систему (возможно, запись файлов изображений на жесткий диск, уменьшение размера оперативной памяти для предотвращения подкачки, ...).Если вы поняли это, вы можете оптимизировать именно эту точку.

Если вы начнете обработку с (cpu-cores) * 2 от низкого до нормального приоритета, ваша система должна быть пригодной для использования.Никто не ожидал, что это убьет систему.

Только мои 2 цента.

...