Сведения о вопросе

FUTER

16:03, 1st July, 2020

Теги

c++   performance   cpu   throttling    

CPU дросселирование в C++

Просмотров: 476   Ответов: 5

Мне просто интересно, есть ли элегантный способ установить максимальную нагрузку CPU для конкретного потока, выполняющего интенсивные вычисления.

Прямо сейчас я нашел самый трудоемкий цикл в потоке (он делает только сжатие) и использую GetTickCount() и Sleep() с жестко заданными значениями. Это гарантирует, что цикл продолжается в течение определенного периода времени, а затем спит в течение определенного минимального времени. Он более или менее выполняет свою работу, т. е. гарантирует, что поток не будет использовать более 50% из CPU.
Однако поведение зависит от количества ядер CPU (огромный недостаток) и просто уродливо (меньший недостаток :)).
Есть идеи?



  Сведения об ответе

ITSME

18:03, 1st July, 2020

Я не знаю ни одного API, чтобы заставить планировщик OS делать то, что вы хотите (даже если ваш поток имеет приоритет ожидания, если нет готовых потоков с более высоким приоритетом, Ваш будет работать). Однако я думаю, что вы можете импровизировать довольно элегантную функцию регулирования, основанную на том, что вы уже делаете. По существу (у меня нет машины Windows dev под рукой):

Выберите количество времени по умолчанию, в течение которого поток будет спать каждую итерацию. Затем на каждой итерации (или на каждой N-й итерации, так что функция регулирования сама по себе не становится значительной нагрузкой CPU),

  1. Вычислите количество CPU времени, которое ваш поток использовал с момента последнего вызова функции регулирования (я буду называть это dCPU). Вы можете использовать GetThreadTimes() API, чтобы получить количество времени выполнения вашего потока.
  2. Вычислите количество реального времени, прошедшего с момента последнего вызова вашей функции регулирования (я буду называть это dClock).
  3. dCPU / dClock - это процент использования CPU (одного CPU). Если он выше, чем вы хотите, увеличьте время сна, если ниже, уменьшите время сна.
  4. Пусть ваш поток спит в течение вычисленного времени.

В зависимости от того, как ваш сторожевой пес вычисляет использование CPU, вы можете использовать GetProcessAffinityMask() , чтобы узнать, сколько CPUs имеет система. dCPU / (dClock * CPUs) - это процент от общего количества доступного времени CPU.

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


  Сведения об ответе

9090

18:03, 1st July, 2020

На linux можно изменить приоритет планирования потока с помощью nice().


  Сведения об ответе

SILA

18:03, 1st July, 2020

Я не могу придумать никакого кросс-платформенного способа того, что вы хотите (или любой гарантированный способ полной остановки), но поскольку вы используете GetTickCount, возможно, вы не заинтересованы в кросс-платформенном способе :)

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

EDIT: Я согласен с Бернардом , вот почему я думаю, что процесс, а не нить может быть более подходящим, но это просто не подходит для ваших целей.


  Сведения об ответе

prince

18:03, 1st July, 2020

Проблема в том, что это ненормально-оставлять CPU в бездействии, пока у вас есть работа. Обычно вы устанавливаете фоновую задачу на приоритет IDLE и позволяете OS управлять ее планированием все время CPU, которое не используется интерактивными задачами.

Мне кажется, что проблема заключается в сторожевом процессе.

Если ваша фоновая задача привязана к CPU, то вы хотите, чтобы она заняла все неиспользованное CPU время для своей задачи.

Может быть, вам стоит посмотреть на исправление сторожевой программы?


  Сведения об ответе

ASSembler

18:03, 1st July, 2020

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


Ответить на вопрос

Чтобы ответить на вопрос вам нужно войти в систему или зарегистрироваться