Я знаю, что если у цикла while есть это тело:
while(a<b){
do_some_calculations
}
он выполнит вычисления, а затем снова проверит цикл while. Но если у меня будет пустой while
цикл:
while(a<b) { }
Как часто он будет проверять условие? Я знаю, что в то время как цикл компилируется в cmp
а также jmp
инструкции (который занимает от одного до двух циклов). Так он будет проверять время цикла каждые 1-2 цикла? Или нет, и есть некоторые вещи, которые я не знаю? Подробные объяснения будут очень полезны.
Постскриптум Вопрос о деталях низкого уровня. Пожалуйста, прочитайте это более внимательно. И я хочу знать общие принципы, а не «это зависит от компилятора и так далее».
P.P.S Давайте предположим, что у нас есть какое-то действительное условие и код, сгенерированный компилятором. Как часто он будет это проверять? Вот в чем вопрос.
Вы, кажется, не задаете правильный вопрос. Если вопрос касается языка, который производит код на ассемблере, вы ответите, что это зависит от компилятора, уровня оптимизации и некоторых других вещей, но самое главное, это будет зависеть от состояние. Каждый цикл будет делать один тест. Если этот тест включает посещение базы данных и проверку чего-либо там, ваш цикл будет выполняться гораздо реже, чем если бы вы сравнивали местное время с некоторым временем истечения (в качестве примера). Без дальнейшего знания о состояние, общий ответ невозможен. Конечно, в зависимости от условия, компилятор иногда может оптимизировать тест, но только если видимое поведение кода не будет зависеть от него. Концептуально условие все еще проверяется на каждой итерации. Пока, конечно, условие не возвращает false и цикл не заканчивается.
Поскольку стандарты допускают множество решений в сгенерированной сборке, ваш вопрос действительно сводится к тому, «что делают компиляторы?» и как таковой отвечает только на примере.
Я выполнил следующий тест с GCC 4.2.1 (на основе Apple Inc., сборка 5658) (сборка LLVM 2336.11.00):
main.cpp:
int main() {
while (true) { }
}
Я скомпилировал его с помощью следующей командной строки:
g++ -S main.cpp
И урезанная версия вывода, main.S, выглядит так:
LBB1_1:
jmp LBB1_1
Так с нет После оптимизации компилятор признает, что нет условий для проверки, поэтому он просто создает жесткий цикл.
Я подозреваю, что другие компиляторы будут делать то же самое, по крайней мере, если включена какая-либо оптимизация. Единственный способ убедиться — это проверить 🙂
Ваш код создаст жесткий цикл, но если он будет пустым, это будет просто бесконечный цикл, как для (;;)
— цикл без условий завершения, и он будет съедать все ресурсы процессора или 100% / number_of_cores, если он многоядерный. В старых операционных системах такой код способен заставить всю систему «зависать», но теперь все планировщики ОС имеют приоритет поэтому он будет выполнять только временной интервал (от 1 до 200 мс в зависимости от ОС), и внутри этого кванта он будет выполняться без прерываний каждые 2-5 циклов, если тело пусто и если компилятор не удаляет ваше условие из-за оптимизации. Так что я думаю, и, как я вижу, многие люди думают, что ваш вопрос является расплывчатым и неправильным.
Он будет генерировать код, который ведет себя как будто условие проверялось каждую итерацию.
Если компилятор может доказать, что проверка условия на каждой итерации не требуется, то он может удалить проверку. Но это зависит от конкретного компилятора и зависит от того, какой именно код вы его кормите.
В while
цикл, условие будет проверено перед вводом
цикл, поэтому он будет проверен еще раз, чем количество
раз вы проходите через цикл.
По крайней мере, в абстрактной машине. Компилятору разрешено
оптимизировать. Таким образом, в вашем примере, если компилятор может знать
значения a
а также b
(потому что, например, они были назначены с
константы непосредственно перед), то он может не генерировать код
сделать проверку. Если цикл явно не содержит ничего
который может изменить условие, он может не генерировать проверку
после первой проверки, так как результаты не могут измениться. Единственный
реальное ограничение на компилятор заключается в том, что наблюдаемый вывод
быть таким же, как если бы сравнение имело место. (Я думаю
компилятору также разрешается предполагать, что цикл завершается
когда-нибудь, и переместить код ниже цикла над ним, и такие вещи, как
тот.)
Предположим, у нас есть какое-то действительное условие и код, сгенерированный компилятором. Как часто он это проверяет? Вот в чем вопрос.
В каждом цикле, если нет оптимизации, никогда, если есть оптимизация, и компилятор понимает, что ваше условие не изменится.
То, как компилятор переводит это, не имеет отношения к C или C ++, пока он работает. Если компилятор видит, что ваш цикл вообще не требуется, он может удалить его. Он может развернуть цикл и удалить все, кроме первой проверки. Все зависит от компилятора и кода, и нет однозначного ответа.
Если компилятор не выполняет никакой оптимизации, он будет делать то, что требует стандарт — одна проверка в начале каждой итерации.