Как рассчитывается загрузка процессора? - PullRequest
65 голосов
/ 20 сентября 2010

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

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

Ответы [ 8 ]

61 голосов
/ 20 сентября 2010

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

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

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

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

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

28 голосов
/ 20 сентября 2010

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

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

Это функция 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);
    }
}

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

13 голосов
/ 20 сентября 2010

Для получения загрузки ЦП периодически проверяйте общее время процесса и находите разницу.

Например, если это время ЦП для процесса 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 , если вы хотите использовать ярлык на общее используемое или простое ЦП.

7 голосов
/ 07 октября 2012

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

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

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

Тогда ваш процент процессора равен (process_time/elapsed_time)*100.0.сделать эти расчеты.

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

2 голосов
/ 20 сентября 2010

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

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

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

1 голос
/ 20 сентября 2010

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

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

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

счетчик, который вам может понадобиться, это PAPI_TOT_CYC, который является числом циклов занятости (если я правильно помню)

0 голосов
/ 03 января 2018
  1. Процессор не «зависает», он просто работает на пиковой мощности, то есть он обрабатывает столько инструкций, сколько он физически способен каждую секунду. Процесс, который вычисляет использование CPU, является некоторыми из тех инструкций. Если приложения пытаются выполнять операции быстрее, чем способен ЦП, то они просто будут задерживаться, что означает «зависание».

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

0 голосов
/ 20 сентября 2010

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

while(true){}

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...