A ветвь - это инструкция в компьютерной программе, которая может вызвать запуск компьютера выполнение другой последовательности команд и, таким образом, отклонение от поведения по умолчанию при выполнении команд по порядку. Ветвь (или ветвление, разветвление) также может относиться к действию переключения выполнения на другую последовательность команд в результате выполнения инструкция по ветке. Инструкции ветвления используются для реализации потока управления в программных циклах и условных выражениях (т. Е. Выполнение определенной последовательности инструкций только при соблюдении определенных условий).
Команда ветвления может быть либо безусловным, что всегда приводит к ветвлению, либо условным ветвлением, которое может или не может вызывать ветвление в зависимости от некоторых условий. Кроме того, в зависимости от того, как он определяет адрес новой последовательности инструкций («целевой» адрес), инструкция ветвления обычно классифицируется как прямая, косвенная или относительная, что означает, что инструкция содержит целевой адрес или указывает, где находится целевой адрес должен быть найден (например, регистр или ячейка памяти), или он указывает разницу между текущим и целевым адресами.
Механически инструкция перехода может изменить счетчик программ (ПК) CPU. Счетчик программ хранит адрес памяти следующей инструкции, которая должна быть выполнена. Следовательно, ветвление может заставить ЦП начать выборку своих инструкций из другой последовательности ячеек памяти.
Когда выполняется переход, программный счетчик ЦП устанавливается на аргумент инструкции перехода. Таким образом, следующая инструкция становится инструкцией по этому адресу в памяти. Следовательно, поток управления меняется.
Когда переход не выполняется, программный счетчик ЦП не изменяется. Следовательно, следующая выполняемая инструкция - это инструкция после инструкции перехода. Следовательно, поток управления не изменился.
Термин ветвь может использоваться при ссылке на программы на языках высокого уровня, а также на программы, написанные на машинном коде или языке ассемблера. В языках программирования высокого уровня ветви обычно принимают форму условных операторов различных форм, которые инкапсулируют последовательность инструкций, которая будет выполняться, если условия удовлетворяются. Инструкции безусловного перехода, такие как GOTO, используются для безусловного «перехода» к другой последовательности команд (начала выполнения).
Инструкции ветвления машинного уровня иногда называют командами перехода. Инструкции перехода на машинный уровень обычно имеют безусловную и условную формы, причем последние могут быть приняты или не приняты в зависимости от некоторых условий. Обычно существуют разные формы для односторонних переходов, часто называемых переходом, и вызовы подпрограмм, известные как вызов, которые автоматически сохраняют исходный адрес в качестве адреса возврата в стеке, позволяя вызывать одну подпрограмму из нескольких мест в коде.
В процессорах с регистрами флагов более ранняя инструкция устанавливает условие в регистре флагов. Более ранняя инструкция может быть арифметической или логической инструкцией. Часто это близко к ветке, хотя не обязательно инструкция непосредственно перед ветвью. Сохраненное условие затем используется в ветви, такой как переход, если установлен флаг переполнения. Эта временная информация часто хранится в регистре флагов, но также может располагаться в другом месте. Конструкция регистра флага проста на более медленных и простых компьютерах. В быстрых компьютерах регистр флагов может стать узким местом для скорости, потому что инструкции, которые в противном случае могли бы работать параллельно (в нескольких исполнительных модулях ), должны устанавливать биты флагов в определенной последовательности.
Существуют также машины (или конкретные инструкции), где условие может быть проверено самой инструкцией перехода, например переход
Некоторые ранние и простые архитектуры ЦП, все еще встречающиеся в микроконтроллерах, могут не реализовывать условный переход, а только условную операцию «пропустить следующую инструкцию». Таким образом, условный переход или вызов реализуется как условный пропуск инструкции безусловного перехода или вызова.
В зависимости от компьютерной архитектуры, язык ассемблера мнемоника для инструкции перехода обычно представляет собой сокращенную форму слова перехода или ответвления слова, часто вместе с другими информативными буквами (или дополнительным параметром), представляющими условие. Иногда также включаются другие детали, такие как диапазон перехода (размер смещения) или специальный режим адресации, который следует использовать для определения фактического эффективного смещения.
В этой таблице перечислены инструкции перехода или перехода на уровне машины, которые можно найти в нескольких хорошо известных архитектурах:
условие или результат | x86 | PDP-11, VAX | ARM (частично 6502) | уравнение |
---|---|---|---|---|
ноль (подразумевает равенство для sub / cmp) | JZ; JNZ | BEQ; BNE | BEQ; BNE | ноль; не ноль |
отрицательный (N), знак (S) или минус (M) | JS; JNS | ИМТ; BPL | ИМТ; BPL | отрицательный; неотрицательное |
арифметическое переполнение (флаг называется O или V) | JO; JNO | BVS; BVC | BVS; BVC | переполнение; не переносить переполнение |
(из add, cmp, shift и т. д.) | JC; JNC | BCS; BCC | BCS; BCC | перенос; не переносить |
без знака ниже (нижний) | JB | BLO | BLO | заимствовать |
без знака ниже или равно (нижний или такой же) | JBE | BLOS | BLS | заимствовать или ноль |
без знака, больше или равно (больше или равно) | JAE | BHIS | BHS | без заимствования |
без знака выше (выше) | JA | BHI | BHI | не заимствовать и не ноль |
со знаком меньше | JL | BLT | BLT | знак ≠ переполнение |
со знаком меньше или равно | JLE | BLE | BLE | (знак ≠ переполнение) или ноль |
со знаком больше или равно | JGE | BGE | BGE | знак = переполнение |
со знаком больше, чем | JG | BGT | BGT | (знак = переполнение), а не ноль |
x86, PDP-11, VAX и некоторые другие, установите флаг переноса, чтобы сигнализировать о заимствовании, и сбросьте флаг переноса, чтобы сигнализировать об отсутствии займа. ARM, 6502, PIC и некоторые другие делают противоположное для операций вычитания. Эта инвертированная функция флага переноса для некоторых инструкций отмечена (), то есть заимствовать = не переносить в некоторых частях таблицы, но если не указано иное, заимствовать нести. Однако аддитивные операции переноса выполняются одинаково в большинстве архитектур.
Для достижения высокой производительности современные процессоры конвейерные. Они состоят из нескольких частей, каждая из которых частично обрабатывает инструкцию, передает свои результаты следующему этапу конвейера и начинает работу над следующей инструкцией в программе. Этот дизайн предполагает, что инструкции будут выполняться в определенной неизменной последовательности. Инструкции условного перехода делают невозможным знание этой последовательности. Таким образом, условные переходы могут вызывать «сбои», при которых конвейер должен быть перезапущен в другой части программы.
Несколько методов повышают скорость за счет уменьшения задержек из условных ветвей.
Исторически предсказание ветвления основывалось на статистике и использовало результат для оптимизации кода. Программист компилирует тестовую версию программы и запускает ее с тестовыми данными. Код теста подсчитывал, как на самом деле были взяты ветки. Статистические данные из тестового кода затем использовались компилятором для оптимизации ветвей выпущенного кода. Оптимизация будет обеспечивать, чтобы самое быстрое направление ветвления (принятое или нет) всегда было наиболее часто используемым путем потока управления. Чтобы разрешить это, процессоры должны быть спроектированы (или, по крайней мере, иметь) предсказуемую синхронизацию ветвления. У некоторых ЦП есть наборы инструкций (например, Power ISA ), которые были разработаны с использованием «подсказок ветвлений», чтобы компилятор мог сообщить ЦП, как следует выполнять каждую ветвь.
Проблема с прогнозированием ветвления программного обеспечения заключается в том, что он требует сложного процесса разработки программного обеспечения.
Для запуска любого программного обеспечения аппаратные предикторы переходов переносили статистику в электронику. Предикторы перехода - это части процессора, которые угадывают результат условного перехода. Затем логика процессора делает ставку на предположение, начиная выполнять ожидаемый поток команд. Пример простой схемы аппаратного прогнозирования ветвлений - предположить, что все обратные ветки (то есть к меньшему программному счетчику) взяты (потому что они являются частью цикла), а все прямые ветки (к большему счетчику программ) не берутся. (потому что они оставляют петлю). Улучшенные предикторы ветвлений разрабатываются и проверяются статистически путем их моделирования в различных тестовых программах. Хорошие предикторы обычно подсчитывают результаты предыдущих выполнений ветви. Тогда более быстрые и дорогие компьютеры могут работать быстрее, если вложить средства в лучшую электронику прогнозирования ветвлений. В ЦП с аппаратным предсказанием ветвления подсказки ветвления позволяют предположительно лучшему предсказанию ветвления компилятора перекрывать более упрощенное аппаратное предсказание ветвления.
Некоторая логика может быть написана без ветвей или с меньшим количеством ветвей. Часто вместо переходов можно использовать побитовые операции, условные перемещения или другие предикации. Фактически, код без ветвлений является обязательным для криптографии из-за временных атак.
Другой метод - слот задержки ветвления. В этом подходе всегда выполняется одна инструкция после перехода. Следовательно, компьютер может использовать эту инструкцию для выполнения полезной работы независимо от того, останавливается ли его конвейер. Этот подход был исторически популярен в компьютерах RISC. В семействе совместимых ЦП он усложняет многоцикловые ЦП (без конвейера), более быстрые ЦП с более длинными, чем ожидалось конвейерами, и суперскалярные ЦП (которые могут выполнять инструкции не по порядку.)