Re[18]: Откуда такая неизбывная приверженность к константам?
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 25.10.24 13:31
Оценка:
Здравствуйте, netch80, Вы писали:

N>Что вы решили назвать тут флагом состояния?


Классический флаг состояния процессора, используемый с незапамятных времен.

N>в знаковой интерпретации это нормально, а в беззнаковой это переполнение. Мы должны детектировать это переполнение?


Если у процессора в ходе выполнения программы возникает любая информация, которая с высокой вероятностью будет полезна этой программе, то да. Именно это и делает тот же x86 с флагами CF/OF, детектируя сразу обе ситуации.

N>Архитектура типа RISC-V намеренно лишена аналога Flags в x86.


И как, этим она существенно выигрывает у архитектур, где флаги есть?

N>Сложение, вычитание, умножение — они все требуют проверок


Именно так. Реализация этих проверок в топологии/микрокоде процессора всегда дешевле, чем в каждой из выполняемых на нем программ.

N>Мы можем добавлять JO или INTO после команды. Мы можем добавлять JC. Вопрос: почему нет парной к ней INTC?


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

N>Есть один вариант решения: флагов нет, ставьте явные проверки по диапазонам и конкретным значениям, где нужно.


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

N>Я бы не против, если б SDIV ставила OF (как бы они ни звались) в случаях деления на 0 или MIN/-1.


Это было бы следуюшим по разумности вариантом при отказе от исключения.

N>вводить ещё и фолт для одного-единственного случая — точно явный и неуместный перекос.


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

Это ж, по сути, то же самое, для чего вводились исключения в C++ — чтобы в ситуации, когда что-то пошло не так, не было риска забыть проверить возвращаемое значение в ситуации, когда не существует заведомо безопасного значения для нештатной ситуации.

N>Неужели не было уже понятно по опыту развития, что в этом нет смысла?


Тогда и в плюсовых исключениях тоже нет смысла. Не в их неправильном использовании, а в механизме, как твковом.

ЕМ>>Если же механизм исключений имеется, но решено отказаться от возбуждения исключения


N>Механизм появляется вместе с более высокими уровнями реализации (в RISC-V). Но его принудительная ориентация на обработку в супервизоре избыточна.


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

N>Сложили 0x01 и 0xFF в беззнаковом контексте, получили 0 вместо 0x100. Не заметили, пошли дальше, нарвались на что-то и приветъ.


Да, возможность нарваться есть. Но она есть наравне с возможностью использовать это поведение для реализации естественных действий — тех же операций по модулю. А вот какие естественные операции могли бы выполняться командой целочисленного деления, возвращающей максимально возможное значение при нулевом делителе?

N>В C нет никаких исключений.


C — не язык "в себе". В C изначально закладывались на то, что исключения, если они есть в архитектуре, поддерживаются средой исполнения.

N>Если где-то вы видите, например, обработчик SIGFPE (в который по POSIX мапится деление на 0, если трапается), то в нём всё равно нельзя без платформенно-специфичных средств вернуться на ту же команду.


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

N>покажите мне такое в x86 или SystemZ (где деление на 0 трапается) такие накопительные флаги?


Зачем нужны непременно накопительные? Как часто в них возникает потребность?

N>В языках-то оно есть. Возьмите какую-нибудь Ada и там всё будет под полным контролем.


А какой ценой?

N>Лучше бы вспомнили историю ATA геометрий — она красочнее.


Там были хоть какие-то объективные основания — разрядности шин, регистров, стоимость тогдашних микросхем и т.п.

N>В общем же случае я думаю, что каждое расширение какого-то реального параметра в 2-3 раза приводит к наступанию на очередной предел.


Это как раз понятно. Непонятно стремление вводить константы вместо переменных, хотя в основе математики лежала противоположная идея.

EM>>выбор константы в 2 Гб тоже был неудачным


N>Он был 99.99% удачен. Остальных давно ждал 64-битный режим


Тогда выбор одного гигабайта вместо двух был бы "удачным на 99.95%". А выбор 512 Мб — "на 99.9%". А фишка в том, что увеличение этой вероятности до максимальной не стоило бы практически ничего, но в итоге цена получилась вполне ощутимой.

N>Тогда на всём экономили.


В загрузчиках MBR/VBR — да. В загрузчике Win95 не было ни малейших причин экономить байты и такты.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.