Design: Арифметика с переносом

Созданный на 28 мар. 2017  ·  7Комментарии  ·  Источник: WebAssembly/design

(Это расширенная версия задачи (https://github.com/WebAssembly/spec/issues/446))

Многоточная арифметика требует специальной обработки. Это доступно в той или иной форме во всех ISA, но в настоящее время недоступно в webasm.

Есть в основном три способа сделать это (мне кажется), ни один из которых не особенно удобен в контексте текущего дизайна:

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

Это традиционный подход в основном аппаратном обеспечении.

Вы получаете инструкции, как

аддк

который добавит два числа и значение флага переноса и установит флаг переноса на результат.

Это не приятно, потому что добавляет специальный регистр.

Вариант 2.
Поддержка формы 60-битной арифметики с 4 битами для флагов.

Вариант 3.
Поддержка арифметики с несколькими словами: сложение принимает 3 аргумента и дает 2 результата.

Такой подход нанесет наименьший ущерб существующей ISA и архитектуре регистров. Однако это будет сложно эффективно сопоставить с существующим оборудованием (не все аппаратные ISA поддерживают загрузку регистра флагов напрямую.

Как бы то ни было, арифметика с множественной точностью очень важна, и ее очень трудно эмулировать без какой-либо простой аппаратной поддержки.

Самый полезный комментарий

Есть ли прогресс в этом вопросе? Перенос и заимствование необходимы для эффективной реализации современной криптографии (например, SIDH). Сложение больших чисел без ADDC в несколько раз медленнее, чем с ADDC. То же самое относится к вычитанию и умножению.

Все 7 Комментарий

Мне кажется, что для варианта 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. В итоге:

  • Вероятно, нам нужны специальные инструкции, потому что эмуляция поведения будет медленной, и мы, как правило, не хотим выполнять магическое сопоставление с образцом, чтобы распознать эмуляцию и превратить ее в эффективный машинный код за кулисами.
  • Мы, конечно же, заботимся о переносе/заимствовании и переполнении; другие флаги подлежат уточнению
  • Мы точно заботимся о сложении и вычитании; умножать, делить, вращать (ротация через перенос распространена, но полезна ли она для Wasm?) TBD
  • Распространенным случаем является то, что мы заботимся только об одном флаге за раз, и, вероятно, этого достаточно для покрытия этого случая, а не общей ситуации «захват флагов A, B и C».
  • Для переноса достаточно инструкции, которая всегда потребляет перенос и всегда производит перенос; варианты, которые потребляют, но не производят или наоборот, не нужны, и их отсутствие, вероятно, не повлияет на вывод хорошего компилятора.
  • Мы хотим мотивировать эту работу данными из существующих хороших библиотек MP (таких как Gnu MP); это могут быть факты (библиотека X имеет или не имеет подпрограммы на ассемблере или использует встроенные функции для использования флагов; она использует инструкции A и B) или данные о производительности (библиотека Y может использовать подпрограммы на ассемблере или эмулировать в C; разница в производительности составляет N% ) или варианты использования (общая бигнум-арифметика, криптография, что еще придет на ум)
  • Мы можем подождать с предложением конкретных инструкций до тех пор, пока не начнем обсуждать инструкции по созданию нескольких значений в целом, например возвраты с несколькими значениями.

Есть ли прогресс в этом вопросе? Перенос и заимствование необходимы для эффективной реализации современной криптографии (например, SIDH). Сложение больших чисел без ADDC в несколько раз медленнее, чем с ADDC. То же самое относится к вычитанию и умножению.

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

Была ли эта страница полезной?
0 / 5 - 0 рейтинги