Дросселирование процессора в C ++

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

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

5.08.2008 07:11:08
Какое видимое поведение вы хотите достичь? То есть, что этот сторожевой пес хочет от ваших тем? Должны ли они использовать больше, чем, скажем, 80% процессора? Может ли установка базового приоритета процесса на Idle возможно успокоить WD?
wordmonger 11.08.2008 19:52:53
5 ОТВЕТОВ
РЕШЕНИЕ

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

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

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

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

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

20
5.09.2008 23:33:42
Если ваша цель состоит в том, чтобы не тратить впустую процессорное время, вероятно, лучшим выбором будет более дешевая эвристика. В зависимости от того, насколько серьезной проблемой для вашего потока является голодание при высокой загрузке системы, вы можете просто проверить истекшее время настенных часов. На x86 это очень дешево, потому что функции времени на основе rdtscдаже не должны входить в режим ядра. Выполнение нескольких системных вызовов, даже nитераций, хуже, чем выполнение одной, если только это не позволит вам значительно увеличить nпроизводительность и при этом получить желаемое поведение.
Peter Cordes 11.05.2016 07:57:39

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

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

РЕДАКТИРОВАТЬ: Я согласен с Бернардом, поэтому я думаю, что процесс, а не поток может быть более подходящим, но он может просто не соответствовать вашим целям.

2
23.05.2017 12:17:58

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

4
5.08.2008 08:03:01
Другие платформы имеют аналогичные функции, см. Также: stackoverflow.com/questions/18884510/… Я думаю, что это может быть хорошим решением проблемы, хотя и с другой семантикой - то есть без гарантии 50% потребления процессора
milianw 8.01.2018 09:03:16

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

Для меня это звучит так, как будто проблема в сторожевом процессе.

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

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

2
6.09.2008 09:01:41
Очень разумно хотеть простоя процессора. Может быть, вы хотите сделать некоторые вычисления, но не волнует, как быстро это будет сделано, если это не раскручивает вентилятор процессора на вашем ноутбуке.
Ringding 21.09.2009 10:32:35

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

0
3.01.2018 18:06:47