почему архитектуры ЦП используют регистр флагов (преимущества?)

15

Некоторые процессоры имеют регистр флагов (ARM, x86, ...), другие нет (MIPS, ...). В чем преимущество наличия инструкции CMP для обновления регистра флагов, сопровождаемой инструкцией ветвления, вместо использования нулевого регистра и условных ветвей для проверки знака, переполнения и т. Д.?

модельный мир
источник

Ответы:

11

В современных микроархитектурах с переименованием регистров стоимость реализации флагов или не флагов очень похожа. Основное различие, о котором я могу думать, состоит в том, что некоторые флаги указывают характеристики значения (является ли значение отрицательным? Является ли значение нулевым? Имеет ли значение четное или нечетное четность?), В то время как некоторые представляют событие, которое произошло во время предыдущей операции (имела ли инструкция add выполнение или переполнение?) Это привело к неидеальной ситуации на MIPS, когда вы хотели симулировать 64-битное сложение на 32-битной архитектуре (или 128-битное сложение на 64-битная архитектура.) На большинстве архитектур с флагом переноса имеется специальныйadd-with-carryинструкция, которая включает флаг переноса из предыдущей инструкции добавления. Это делает моделирование арифметики с высокой точностью относительно недорогим на многих архитектурах с регистрами флагов.

С другой стороны, тестирование N-битного регистра на ноль или не на ноль на самом деле удивительно дорого. Чтобы проверить N-битный регистр на ноль, вам нужно выполнить N-битную операцию NOR, которая требует уровней логики для вычисления. На архитектурах с регистрами флагов дополнительная логика для вычисления нуля / не нуля в конце этапа ALU может привести к замедлению тактового генератора (или заставить ALU выполнять две операции цикла). По этой причине, я думаю, некоторые В архитектурах, как в SPARC, было две версии каждой арифметической операции: одна для установки флагов, а другая - нет.О(журналN)

Но MIPS здесь ничего не сохраняет. Они просто перенесли проблему в другое место. На MIPS есть branch-on-equalинструкция. Это означает, что на самом деле инструкция ветвления должна иметь этап ALU (включая что-то вроде побитовой xorоперации, за которой norследует сокращение до одного равного / не равного бита), прежде чем определять, каким образом идет ветвление.

Архитектура DEC Alpha пыталась разделить разницу, используя хитрость. У DEC Alpha не было регистров флагов, но также не было branch-on-equalинструкции. Вместо этого все инструкции перехода смотрят на состояние единого регистра общего назначения. Там будет branch-on-zero, branch-on-not-zero, branch-on-less-than-zeroи т.д. Хитрость заключается в том, что вы можете дать каждый общего назначения зарегистрировать дополнительный бит 65 - й , который говорит вам ли остальные 64 бита равны нулю или нет. Это больше похоже на наличие регистра флагов: все инструкции перехода смотрят на один бит (который уже рассчитан), чтобы принять свое решение, но теперь вы вернулись к выяснению, как вычислить этот дополнительный нулевой бит индикатора во время обычного АЛУ цикл. (И вы все еще не можете сделать арифметику с высокой точностью, просто взглянув на флаг переноса из предыдущей операции.)

Блуждающая логика
источник
2
Операции настройки не-CC были (насколько я понимаю) оптимизацией компилятора , что позволяло компилятору планировать инструкции CC-настройки на ранних этапах без того, чтобы значение было перекрыто последними инструкциями. PowerPC750 поместил регистры условий (8 4-битных регистров) ближе к внешнему интерфейсу так, чтобы взятая ветвь, попавшая в кэш целевых команд ветвления и имеющая условие, доступное достаточно рано, могла разрешить принятую ветвь без штрафа. (AT & T CRISP также использовал раннее разрешение ветвлений.) Небольшое количество и специализация CC делают это более практичным.
Пол А. Клейтон,
Деталь: все вычисления флагов не сделаны равными. Представьте, что ваш процессор имеет традиционные флаги NZVC. Если всем инструкциям ALU разрешено обновлять флаги, вы должны поместить генерацию флагов после сумматора / вычитателя и нескольких мультиплексоров. Отрицательный флаг прост, это просто MSB, тогда как нулевой флаг стоит дорого и зависит от каждого бита. Теперь, если вы ограничите флаги инструкциями сравнения (и проверки битов), флаги нуля можно вычислить с помощью параллельных значений XOR для исходных операндов, не дожидаясь результата вычитания. Вычисление флага Z после добавления практически бесполезно.
TEMLIB
7

1 С точки зрения ISA

  1. Наличие инструкций по тестированию, которые устанавливают только флаги, - это просто способ уменьшить давление в регистре в архитектурах с отсутствием регистра. Если у вас достаточно регистров, просто измените один из них и проигнорируйте результат. Хитрость в том, чтобы иметь регистр 0 с входным значением 0, это всего лишь уловка кодирования, удобная, когда у вас достаточно регистров, что фиксация одного из них в 0 лучше, чем увеличение количества инструкций. Тогда его удобно использовать и в качестве цели (это уменьшает количество ложных зависимостей).

  2. Кодировка снова. Если вы закодируете условие в прыжках, у вас будут прыжки с 3 операндами (два сравниваемых объекта и цель перехода), два из которых вы хотите использовать в качестве непосредственных значений, один из которых вы хотите иметь большой размер возможно (переходы часто имеют свой собственный формат кодирования, чтобы цель могла использовать как можно больше битов). Или вы отбрасываете возможности.

  3. Использование флагов дает вам больше возможностей для их установки. Не только операции сравнения могут устанавливать флаги, но и все, что вы хотите. (С учетом того, что чем больше у вас операций, которые устанавливают флаги, тем тщательнее вы должны быть уверены, что последняя операция, которая устанавливает флаги, является той, которую вы хотите). Если у вас есть флаги, вы можете протестировать количество условий (часто 16), умноженных на количество инструкций, которые могут установить флаги (Если вы не используете флаги, вы получите примерно столько же условных переходов, сколько вы есть вещи для тестирования или есть вещи, которые вы не позволяете тестировать так же легко (например, переносить или переполнять).

2 С точки зрения исполнителя

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

  2. Наличие флагов означает, что многие инструкции имеют несколько результатов (естественный результат и каждый из измененных флагов). А из микроархитектуры POV многократные результаты плохие (вы должны следить за их связью). Когда у вас есть только один набор флагов, которые вводят зависимости (ненужные, если флаг не используется), вы должны обрабатывать так или иначе. Опять же, это особенно верно для более простых реализаций: когда вы переходите к высокопроизводительному процессору, использующему все приемы книги, дополнительные трудности затмеваются остальной частью процессора.

AProgrammer
источник
2

На 32-битном компьютере команда «добавить с переносом», используемая как часть последовательности сложения с множественной точностью, должна принимать операнды на 65 битов и вычислять сумму в 33 бита. Спецификации регистра источника будут определять, откуда должны поступить 64 бита операнда, а спецификация регистра назначения скажет, куда должны идти младшие 32 бита результата, но что делать с операндом «добавить один дополнительный» или старшим битом. результата? Разрешить указывать в качестве части инструкции, откуда должен поступать дополнительный операнд и куда должен идти дополнительный результирующий бит, было бы умеренно полезно, но, как правило, это было бы не так полезно, чтобы оправдать дополнительное поле в коде операции. Наличие фиксированного «местоположения» для обработки флага переноса может быть немного неудобным с точки зрения планирования команд, но это '

Если кто-то пытался создать набор команд, чтобы разрешить арифметику с множественной точностью, но каждая команда была ограничена двумя 32-разрядными операндами и одним 32-разрядным операндом-адресатом, можно было бы реализовать 64-разрядное «добавление» в четырех инструкциях: «набор От r5 до 1, если r0 + r2 будет нести или обнулять иначе; вычислить r4 = r1 + r3; вычислить r5 = r4 + r5; вычислить r4 = r0 + r2 ", но для выхода за пределы этого потребуется три инструкции для каждого дополнительного слова. Наличие флага переноса в качестве дополнительного источника и места назначения снижает стоимость до одной инструкции на слово.

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

ldr  r0,[r1]
add  r0,r0,r2
eors r4,r5,r6

исполнительный модуль может довольно легко распознать, что третья инструкция может быть выполнена без необходимости ждать чтения данных [r1], но если бы была вторая инструкция, это было adds r0,r0,r2бы возможно только в том случае, если исполнительный модуль мог гарантировать, что к тому времени что-либо попытается использовать В флагах нулевой флаг будет содержать значение, установленное в третьей инструкции, но флаг переноса будет содержать значение во второй.

Supercat
источник
1
«бит управления инструкцией, обновляет ли инструкция регистр флага»: доступно, например, в PowerPC, SPARC.
TEMLIB
MIPS использует «r5 = r1 + r2; установите r6, если r6 меньше r1; r7 = r3 + r4; r5 = R5 + R6;». Некоторые расширения SIMD могут использовать сравнения, которые устанавливают все биты в ноль или единицу (т. Е. В ноль или -1 в два целых числа дополнения), чтобы найти перенос и вычитание для применения переноса.
Пол А. Клейтон,
@ PaulA.Clayton: я думаю, что вы имели в виду «если r5 меньше r1». Как MIPS справится с более длительной математикой? Требуется ли три, более трех или менее трех инструкций на слово?
суперкат
@supercat Да, это должно было быть «установлено r6, если r5 меньше, чем r1»!
Пол А. Клейтон,
@ PaulA.Clayton: Как можно добавить, например, два 64-словных (2048-разрядных) числа на 32-разрядном MIPS? Есть ли эффективный способ справиться с переносами в и из средних этапов?
суперкат
0

Простой ответ ... быстрая дешевая операция с памятью, которая не требует абсолютно никакого внутреннего использования, кроме самой инструкции. Его можно использовать как bool-стек без стека или бита процесса, без памяти.

SkipBerne
источник
1
Этот ответ довольно легок в деталях. Длинные ответы не обязательно требуются, но что-то более конкретное было бы явным улучшением.
Дэвид Ричерби
установка флага или сравнение значения флага - это отдельная инструкция без какой-либо другой информации в форме аргументов, которая будет включена в код сборки. флаги также являются результатом работы или теста апроцессора и могут эффективно использоваться для ветвления. это фактический бит, который переключается или устанавливается при сравнении двух значений в регистрах.
SkipBerne