Подтвердить что ты не робот

Блокировка процессора в С++

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

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

4b9b3361

Ответ 1

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

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

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

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

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

Ответ 2

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

Ответ 3

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

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

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

Ответ 4

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

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

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

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