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

Почему пустая петля использует столько процессорного времени?

Если в моем коде есть пустой цикл while, например:

while(true);

Он будет использовать процессор до 25%. Однако, если я сделаю следующее:

while(true)
    Sleep(1);

Он будет использовать только около 1%.

Так почему это?

Обновление: спасибо за все замечательные ответы, но я думаю, я действительно должен был задать этот вопрос, Каков алгоритм сна()?, который больше нужен Я хотел знать.

4b9b3361

Ответ 1

В первом случае условие true должно быть проверено процессором так часто, как приложение может получить фокус. Как только приложение получает внимание к процессору, оно проверяет true, как и любое другое условие цикла, чтобы увидеть, может ли выполняться следующая инструкция в цикле. Конечно, следующая инструкция в цикле также true. В основном, вы вынуждаете процессор постоянно определять, истинно ли значение true, которое, хотя и тривиально, когда выполняется, постоянно болото обрабатывает процессор.

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

Ответ 2

Я собираюсь предположить, что у вас четыре ядра на вашем многоядерном процессоре, что объясняет 25%, поскольку вы полностью связываете один процессор с занятым циклом, поскольку единственный разрыв в нем - это когда приложение задерживается поэтому может выполняться другое приложение (но это может не произойти в зависимости от нагрузки).

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

Ответ 3

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

Ответ 4

У вас есть четырехъядерная машина, верно? Если да,

while(true);

фактически использует 100% одного из ваших ядер.

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

Sleep(1);

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

Ответ 5

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

Оператор сна во втором цикле освобождает управление операционной системой не менее 1 миллисекунды. В этом состоянии приложение эффективно останавливается и не продолжает обработку. Результат остановки для x количества времени уменьшает количество сравнений, и, следовательно,% циклов процессора cpu может выполнять процессор в секунду.

Что касается 25%, процессоры Intel, поддерживающие Hyperthreading или многоядерные процессоры, могут испортить статистику производительности. Пустой цикл эффективно перекрывает хотя бы одно ядро ​​процессора.

В тот момент, когда многоядерные процессоры не существовали, у пользователей была потребность в многопроцессорной обработке/задании. Есть несколько способов, которыми была достигнута иллюзия одновременного запуска нескольких процессов.

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

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

Ответ 6

В принципе, у вас есть несколько состояний "планировщик процессов". Я назову три из них. Один: Готов Два: запуск Три: заблокировано

Эти состояния/очереди существуют только из-за ограниченного количества ядер на вашем процессоре. В Готов запланированы процессы, которые полностью готовы к выполнению. Им не нужно ждать ввода, времени или чего-то еще. При запуске процессы фактически "имеют" процессор и, следовательно, работают. Состояние Заблокировано означает, что ваш процесс ожидает, что произойдет событие перед очередью для процессора.

Когда вы продолжаете тестировать пока (true), вы сохраняете свой процесс в очереди готов. Планировщик процесса дает ему определенное количество времени, и через некоторое время удаляет его из процессора (помещая его в конец "готовой" очереди). И, таким образом, ваш процесс будет продолжать возвращать "on" процессор, сохраняя его занятым.

Когда вы выполняете оператор "sleep", ваш процесс не будет планироваться в процессе до тех пор, пока не будет выполнено условие готовности - в этом конкретном случае, пока время, прошедшее после команды "sleep" <= 1000 мс.

Ответ 7

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

Ответ 8

Потому что вы держите процессор занятым, вычисляя цикл через annd.

Использование Sleep фактически позволяет другим потокам выполнять на CPU и вместе с очень коротким переключателем контекста выглядит так, как будто процессор свободен в течение короткого времени.

Ответ 9

Поскольку Sleep в основном говорит процессору о переключении контекстов и позволяет некоторым другим программам получать больше времени процессора.

Ответ 10

Cpu может выполнять несколько миллиардов операций в секунду. Это означает, что пустая петля запускается mybe миллион раз в секунду. Цикл с инструкцией sleep работает только 1000 раз в секунду. В этом случае процессор имеет несколько операций в секунду, чтобы делать другие вещи.

Скажем, у нас есть процессор 3GHz. 3Ghz = 3 000 000 000 Гц - процессор может запускать цикл три биллиона раз в секунду (простое).

С помощью инструкции sleep цикл выполняется 1000 раз в секунду. Это означает, что загрузка процессора равна

1000/3 000 000 000 * 100 = 0,0001%

Ответ 11

Спящий режим во втором показан как "выход" для планировщика процессов ОС.

Ответ 12

Потому что это будет работать все время.

Обычные программы не безумно запускают инструкции все время.

Например, программы GUI просто сидят без ожидания в ожидании событий (например, ввод с клавиатуры),

Примечание: сидит без дела!= while (true);

Они только запускают команды при поступлении событий, а код обработки событий обычно мал и работает очень быстро (в противном случае программа будет не отвечать). Представьте, что ваше приложение получает 5 нажатий клавиш в секунду, сколько процессорного времени потребуется?

Вот почему обычные процессы не занимают столько CPU.

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

Бесконечные циклы на самом деле - это что-то для запуска (повторяющаяся команда перехода).

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

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

Еще один экземпляр процесса, стоящего без дела, - это Sleep(1), здесь он явно указывает ОС не давать ему какое-либо время cpu до истечения указанного времени.