(Это расширенная версия задачи (https://github.com/WebAssembly/spec/issues/446))
Многоточная арифметика требует специальной обработки. Это доступно в той или иной форме во всех ISA, но в настоящее время недоступно в webasm.
Есть в основном три способа сделать это (мне кажется), ни один из которых не особенно удобен в контексте текущего дизайна:
Вариант 1. Добавьте специальный регистр флагов вместе с инструкциями, которые выполняют арифметические действия с этим регистром.
Это традиционный подход в основном аппаратном обеспечении.
Вы получаете инструкции, как
аддк
который добавит два числа и значение флага переноса и установит флаг переноса на результат.
Это не приятно, потому что добавляет специальный регистр.
Вариант 2.
Поддержка формы 60-битной арифметики с 4 битами для флагов.
Вариант 3.
Поддержка арифметики с несколькими словами: сложение принимает 3 аргумента и дает 2 результата.
Такой подход нанесет наименьший ущерб существующей ISA и архитектуре регистров. Однако это будет сложно эффективно сопоставить с существующим оборудованием (не все аппаратные ISA поддерживают загрузку регистра флагов напрямую.
Как бы то ни было, арифметика с множественной точностью очень важна, и ее очень трудно эмулировать без какой-либо простой аппаратной поддержки.
Мне кажется, что для варианта 3 есть правдоподобные оптимизации, которые сделают это практичным. Предположим, {i32,i64}.addc принимает три входа, op2 вверху, op1 внизу, перенос внизу и производит два выхода, результат вверху и перенос под ним. Ради аргумента предположим, что перенос всегда того же типа, что и другие операнды. Определите addc только для использования младшего бита переноса и для того, чтобы перенос, оставшийся после операции, был равен нулю или единице. Скажем, все теперь разумно настроено для добавления из нескольких слов. В правильно развернутом цикле компилятор JIT/Wasm действительно должен видеть, что распространяется перенос, и генерировать хороший код. (И если цикл не развернут, то накладные расходы цикла в любом случае разбавят извлечение/вставку переноса.) Я думаю, что в худшем случае код без ветвлений для извлечения переноса должен быть mov rd, 0; adc rd, 0
; для вставки что-то вроде and rc, 1; add rc, ~0
, где rc — регистр, содержащий значение, которое следует рассматривать как перенос.
В ARM потребление переноса отделено от создания переноса: ADC потребляет, ADC.S потребляет и производит, ADD.S только производит. Хотели бы мы все эти варианты? А как быть с переливом?
(Может быть и четвертый вариант, когда мы добавляем операцию работы и ветвления по условию, которая одновременно выдает результат и переходит к метке или нет, например, i32.addc op1 op2 carry L
будет переходить к L при наборе переноса. и провалиться при переносе, и в любом случае оставить результат в стеке, но в целом это кажется сложнее, чем три предложенных вами варианта.)
Есть ли кто-нибудь, готовый поддержать это предложение? Нам понадобится предлагаемая семантика, двоичное кодирование, и я бы хотел хотя бы несколько вариантов использования и реализацию с показателями производительности для этих вариантов использования (сравните текущий MVP WebAssembly с этим предлагаемым дополнением и собственным кодом).
В принципе, я был бы готов отстаивать это.
Однако личные изменения означают, что мои ресурсы ограничены, по крайней мере, на следующие несколько месяцев.
———
Фрэнк МакКейб
Старший архитектор программного обеспечения
Телефон: 650-740 6673 | Электронная почта: [email protected] ваше имя@instartlogic.com
Начальная логика | 450 Lambert Ave, Пало-Альто, Калифорния 94306 | instartlogic.com http://instartlogic.com/
11 мая 2017 г. в 10:14 JF Bastien [email protected] написал:
Есть ли кто-нибудь, готовый поддержать это предложение? Нам понадобится предлагаемая семантика, двоичное кодирование, и я бы хотел хотя бы несколько вариантов использования и реализацию с показателями производительности для этих вариантов использования (сравните текущий MVP WebAssembly с этим предлагаемым дополнением и собственным кодом).
—
Вы получаете это, потому что вы создали тему.
Ответьте на это письмо напрямую, просмотрите его на GitHub https://github.com/WebAssembly/design/issues/1021#issuecomment-300856161 или отключите ветку https://github.com/notifications/unsubscribe-auth/ADfCzd9le4ufXm6DSsArpfXCYsGdV7UIks5r40H5gaJpZM4MrKma .
У меня, вероятно, будет время, чтобы посвятить этому, хотя и не очень много, до июня или около того, а затем до осени. IMO, эта функциональность довольно важна, и я думаю, что флаг переполнения так же важен, как и флаг переноса, хотя и с разными вариантами использования (переход fixnum -> bignum динамических языков).
Сегодня обсуждал это с некоторыми людьми из Mozilla. В итоге:
Есть ли прогресс в этом вопросе? Перенос и заимствование необходимы для эффективной реализации современной криптографии (например, SIDH). Сложение больших чисел без ADDC в несколько раз медленнее, чем с ADDC. То же самое относится к вычитанию и умножению.
Я думаю, что мы, по крайней мере, ждем завершения работы с несколькими значениями, чтобы мы могли легко выразить операцию с более чем одним результатом. Многозначность "почти есть".
Самый полезный комментарий
Есть ли прогресс в этом вопросе? Перенос и заимствование необходимы для эффективной реализации современной криптографии (например, SIDH). Сложение больших чисел без ADDC в несколько раз медленнее, чем с ADDC. То же самое относится к вычитанию и умножению.