Здравствуйте, netch80, Вы писали:
N>Тему с накопительным поведением вы проигнорировали.
Я задал вопрос: "Зачем нужны непременно накопительные? Как часто в них возникает потребность?". Вы не ответили.
N>Авторы считают, что отсутствие зависимости по скрытому значению — да, помогает в реализации.
В каком смысле это значение более "скрыто", нежели значения регистров или ячеек памяти? По состояниям отдельных флагов можно выполнить переход, их можно использовать в операциях, можно прочитать явно.
N>у x86 то же самое в векторных операциях... потому что не может быть одного флага результата на 4-8-16 разных операций впараллель
Насколько часто при векторных операциях необходимы ветвления по промежуточным результатам? Там, как правило, безусловные, "пакетные" алгоритмы.
ЕМ>>Реализация этих проверок в топологии/микрокоде процессора всегда дешевле, чем в каждой из выполняемых на нем программ.
N>Ну и где они в x86?
Во флагах состояния, вестимо.
Пусть и не все, хотелось бы больше.
ЕМ>>Потому, что перенос очень часто является следствием нормального выполнения, и как-то специально его обрабатывать не требуется,
N>Нет здесь такой несимметричности.
Если сейчас навскидку скачать любой бинарник и дизассемблировать его — уверены, что действий со знаковыми величинами, при которых
штатно возникает переполнение, найдем примерно столько же, сколько и для беззнаковых?
N>где говорят про экономию ресурсов
Экономия на флагах состояния на фоне сложности любого процессора даже 30-40-летней давности — это фикция, тех ресурсов там совершенно ничтожное количество, исчисляемое единицами логических элементов.
N>где про резкое облегчение дизайна за счёт отсутствия единого регистра флагов и за счёт этого лучшую параллельность.
Тоже непонятно, где здесь может быть "резкое облегчение". Параллельное выполнение даже простых арифметических операций требует наличия нескольких полноценных АЛУ, а флаги состояния из такого АЛУ выходят либо сами по себе, либо путем добавления единиц логических элементов.
Некоторое упрощение получить можно, "резкое" — тупо неоткуда.
N>Заметьте, Intel в своём проекте APX намеревается сделать то же самое.
В последнее время явно видна тенденция сращивания функций процессора и компилятора. Если существующие архитектуры еще предполагали написание программы человеком на ассемблере, то новые уже предполагают только машинную генерацию кода. В таких условиях разумно целиком оптимизировать связку "компилятор+процессор" — возможно, в ней флаги состояния действительно получаются избыточными.
Но и x86, и ARM проектировались во времена, когда написание кода человеком на ассемблере использовалось достаточно широко.
ЕМ>>Это было бы следуюшим по разумности вариантом при отказе от исключения.
N>Как раз более разумно, чем исключение
Если предполагается, что программа
всегда будет генерироваться автоматически, и статистика показывает, что затраты на проверку после каждого деления потеряются на общем фоне, то да.
EM>> Порождать исключения для арифметических переполнений нет смысла, поскольку они очень часто возникают в совершенно нормальных, запланированных ситуациях.
N>Кажется, единственный вариант, при котором это возможно, это арифметика "по модулю". Назвать такое "очень часто" — это слишком сильная натяжка.
Например, там, где нуль/ненуль нужно преобразовать в 0/1 или 0/-1, компиляторы вовсю используют комбинации из neg, sbb, inc и and. А счетчики с переполнением часто используются для отслеживания небольших временнЫх интервалов в алгоритмах реального времени.
N>мы знаем, что "нормальных, запланированных" ситуаций с переполнениями почти нет
Хорошо Вам, что "вы знаете".
Я вот их использую регулярно, и столь же регулярно вижу в коде, который делает компилятор (те же преобразования int в bool). А вот операций с
заведомо знаковыми величинами, при которых знаковое же переполнение было бы штатной ситуацией, и не требовало специальных действий, я с ходу даже не припомню, как и в случае деления на нуль.
ЕМ>>чтобы в ситуации, когда что-то пошло не так, не было риска забыть проверить возвращаемое значение в ситуации, когда не существует заведомо безопасного значения для нештатной ситуации.
N>Ну и почему на это плюют во всяких x86 для трёх операций из четырёх (это ещё и если не считать сдвиги за арифметику со степенью двойки, тогда окажется, что в 7 из 8)?
Где можно найти примеров, в которых это "наплевательство" требуется обставлять ловушками?
ЕМ>>Тогда и в плюсовых исключениях тоже нет смысла. Не в их неправильном использовании, а в механизме, как твковом.
N>Передёргиваете. Я ясно сказал, что возможность проверки есть и там, где её применяют, проблема детектируется. Может, чуть заморочно.
Пытаюсь увидеть разницу, но не вижу. Если в процессоре не возбуждать исключения при делении на нуль, а возвращать специальное значение, необходимо добавлять проверку после каждого деления; случаев, когда программа может безопасно использовать специальное значение, найдется очень мало. В C++ тоже можно обойтись без исключений, возвращая специальное значение, и тоже далеко не всегда его можно подобрать так, чтобы продолжение без проверки было безопасным. Разницу вижу только в том, что код для процессора сейчас преимущественно делает компилятор, который не забудет добавить проверку, а программы на C++ преимущественно делает человек, который может забыть.
N>Ситуацию незамеченного деления на 0 за весь свой опыт я видел только одну
Удивлен. Уж насколько я всегда избегал математики в своих программах, но у меня и делений хватает, и случаев ошибочного деления на нуль было предостаточно. Если б они не порождали исключений, и компилятор не спасал бы автоматической проверкой, я бы вздернулся их все разыскивать.
N>случаи проблем из-за непойманного переполнения при остальных трёх арифметических операциях — уже десятки.
Этих тоже хватало. Но, если б каждое такое переполнение порождало исключение, было бы еще хуже.
N>Проверка каждого результата при укладке в целевую переменную, на её границы, плюс операций с базовым размером значения (как int и long в C) на переполнения. Не сильно большая цена за реальную безопасность.
Это было бы полезно во всех без исключения языках, но не безусловно, а при возможности независимого управления каждым видом проверок.
N>Ну вот вы почему-то постановили, что константы разрядности в виде 32 и 64 они оправданны, а остальные — нет.
Это не "мы постановили", это непосредственно вытекает из
физических, железных характеристик архитектуры. А числа вроде 2 Гб для границы АП, или 480 Мб для бессбойной загрузки Win95, ниоткуда не вытекают, а возникают произвольно.
N>жалобы при переходе на S/360, что 32-битный float был заметно хуже 36-битного по свойствам.
Вроде неудивительно. Чем не устраивал 64-битный?
N>Надо было таки оставить разрядности типа 36 и 72?
Они и так оставались доступными через 64- и 128-разрядные. Или Вы о хранении чисел в памяти?
N>увеличение выше 2GB реально стоило — мороки программистам и производительности ядру. Сплошная перекачка данных между буферами.
Почему при границе в 2 Гб "сплошной перекачки" нет, а при смещении на те же 3 Гб вдруг потребовалась?