2008-08-05 2 views
37

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

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

+1

Какое видимое поведение вы хотите достичь? То есть, чего хочет этот сторожевой псов от ваших потоков? Должны ли они отнюдь не использовать больше, чем, скажем, 80% процессора? Можно ли настроить приоритет технологической базы на Idle, возможно, успокоить WD? – wordmonger 2008-08-11 19:52:53

ответ

17

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

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

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

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

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

+0

Если ваша цель - не тратить время на процессор, более дешевая эвристика, вероятно, лучший выбор. В зависимости от того, какая проблема связана с тем, что ваша нить голодает сама при высокой нагрузке на систему, вы можете * просто * проверить истекшее время настенных часов. На x86 это очень дешево, потому что функции времени, основанные на `rdtsc`, даже не нужно вводить в режим ядра. Создание нескольких системных вызовов даже «n» итераций хуже, чем создание только одного, если только оно не позволяет вам увеличивать `n` на много и все равно получать нужное поведение. – 2016-05-11 07:57:39

2

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

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

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

4

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

+0

Другие платформы имеют схожие функции, см. Также: https://stackoverflow.com/questions/18884510/portable-way-of-setting-stdthread-priority-in-c11 Я думаю, что это может быть хорошим решением проблемы, хотя с другой семантикой - то есть без гарантии 50% -ного потребления ЦП – milianw 2018-01-08 09:03:16

2

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

Звук для меня, как проблема, это процесс сторожевого таймера.

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

Возможно, вам стоит взглянуть на фиксацию программы сторожевого таймера?

+1

Очень разумно хотеть простоя процессора. Возможно, вы хотите сделать некоторые вычисления, но не волнует, как быстро это делается, если оно не разворачивает вентилятор процессора на вашем ноутбуке. – Ringding 2009-09-21 10:32:35

0

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

Смежные вопросы