Как рассчитывается использование ЦП?

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

Я всегда задавался вопросом, как процессор вычисляет, сколько его вычислительной мощности используется? Кроме того, если CPU зависает, делая некоторые интенсивные вычисления, как он может (или что-то еще обрабатывает эту активность) изучить использование, не зависая?

8 ответов


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

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

это функция Linux в (вырванный из Википедии), которая выполняет указанный расчет:

#define FSHIFT   11  /* nr of bits of precision */
#define FIXED_1  (1<<FSHIFT) /* 1.0 as fixed-point */
#define LOAD_FREQ (5*HZ) /* 5 sec intervals */
#define EXP_1  1884  /* 1/exp(5sec/1min) as fixed-point */
#define EXP_5  2014  /* 1/exp(5sec/5min) */
#define EXP_15 2037  /* 1/exp(5sec/15min) */

#define CALC_LOAD(load,exp,n) \
    load *= exp; \
    load += n*(FIXED_1-exp); \
    load >>= FSHIFT;

unsigned long avenrun[3];

static inline void calc_load(unsigned long ticks)
{
    unsigned long active_tasks; /* fixed-point */
    static int count = LOAD_FREQ;

    count -= ticks;
    if (count < 0) {
        count += LOAD_FREQ;
        active_tasks = count_active_tasks();
        CALC_LOAD(avenrun[0], EXP_1, active_tasks);
        CALC_LOAD(avenrun[1], EXP_5, active_tasks);
        CALC_LOAD(avenrun[2], EXP_15, active_tasks);
    }
}

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


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

  • когда мы переключаемся на простаивающую задачу, установите t = текущее время
  • когда мы переключаемся от задачи простоя, добавьте (текущее время-t) к общей сумме

Если мы возьмем два образца нарастающим итогом N секунд, мы можем рассчитать процент тех N секунд, потраченных на выполнение задачи простоя как (второй образец-первый образец) / n

обратите внимание, что это то, что делает ОС, а не процессор. Концепция задачи не существует на уровне процессора! (На практике задача простоя будет помещать процессор в спящий режим с инструкцией HLT, поэтому процессор знает, когда он не используется)

Что касается второго вопроса, современные операционные системы упреждающе многозадачны, что означает, что ОС может переключиться с вашей задачи в любое время. Как ОС на самом деле украсть процессор из вашей задачи? Прерывает:http://en.wikipedia.org/wiki/Interrupt


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

например, если это время процессора для процесса 1:

kernel: 1:00:00.0000
user:   9:00:00.0000

и затем вы получаете их снова через две секунды, и они:

kernel: 1:00:00.0300
user:   9:00:00.6100

вы вычитаете время ядра (для разницы 0.03) и время пользователя (0.61), сложите их вместе (0.64), и разделите временем образца 2 секунд (0.32).

таким образом, за последние две секунды процесс использовал в среднем 32% времени процессора.

конкретные системные вызовы, необходимые для получения этой информации, (очевидно) различны на каждой платформе. На Windows, вы можете использовать GetProcessTimes или GetSystemTimes если вы хотите, чтобы ярлык в общей сумме используется или время простоя процессора.


один из способов сделать это следующим образом:

выбрать интервал выборки, скажем каждые 5 минут (300 секунд) от реального времени. Вы можете получить это от gettimeofday.

получите время процесса, которое вы использовали за эти 300 секунд. Вы можете использовать times() позвоните, чтобы получить это. Это было бы new_process_time - old_process_time, где old_process_time - это время процесса, которое вы сохранили с последнего интервала времени.

ваш процент процессора тогда (process_time/elapsed_time)*100.0 Вы можете установить сигнал тревоги, чтобы сигнализировать вам каждые 300 секунд сделать эти расчеты.

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


Это мое основное понимание от небольшого воздействия подобного кода. Такие программы, как Диспетчер задач или системные вызовы доступа к виджетам, такие как NtQuerySystemInformation (), и используют информацию, собранную из ОС, чтобы сделать простой расчет процента времени, когда процессор простаивает или используется (в стандартном количестве времени). Процессор знает, когда он простаивает, поэтому он может определить, когда он не простаивает. Эти программы действительно могут засориться ... Диспетчер задач моего паршивого ноутбука зависает все время при расчете использования процессора, когда он заполняется на 100%.

прохладный бит кода примера можно найти на веб-сайте MSDNs, который показывает вызовы функций для расчета использования ЦП для набора инструкций:http://msdn.microsoft.com/en-us/library/aa364157 (VS.85).aspx

то, что делают эти системные вызовы, - это доступ к коду ядра, который я считаю... который выходит за рамки моего понимания.


существует несколько способов сделать это:

процессор поддерживает несколько счетчиков, которые измеряют производительность, вы можете получить к ним доступ с помощью интерфейса Papi. например, вот краткое введение: http://blogs.oracle.com/jonh/entry/performance_counter_generic_events

также:http://www.drdobbs.com/tools/184406109

счетчик можно будет PAPI_TOT_CYC что количество рабочих циклов (если я помню правильно)


ну, насколько я понимаю, там гигант

while(true){}

цикл, который запускают операционные системы. Ваш процесс управляется из этого цикла. Он позволяет выполнять внешний код непосредственно на процессоре кусками. Не преувеличивая слишком много, это uber-упрощение того, что на самом деле происходит.


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

  2. расчет загрузки ЦП основан на общем доступном использовании. Таким образом, если процессор имеет два ядра, и одно ядро имеет 30% использования, а другое-60%, общая загрузка составляет 45%. Вы также можете увидеть использование каждого отдельного ядра.