Векторная двойная арифметика с плавающей точкой - PullRequest
1 голос
/ 19 апреля 2019

Существуют рабочие нагрузки, для которых плавающая точка двойной точности не вполне адекватна, следовательно, требуется квадратическая точность. Это редко предоставляется аппаратно, поэтому обходной путь должен использовать double-double, где 128-разрядное число представлено парой 64-разрядных чисел. Это не настоящая четверная точность IEEE-754 - во-первых, вы не получаете никаких дополнительных экспонентных битов - но для многих целей достаточно близки и намного быстрее, чем просто программная реализация.

Многие компьютеры предоставляют векторные операции с плавающей точкой, и было бы желательно использовать их для операций двойного-двойного. Это возможно? В частности, глядя на реализацию double-double в https://github.com/JuliaMath/DoubleDouble.jl/blob/master/src/DoubleDouble.jl, мне кажется, что для каждой арифметической операции требуется по крайней мере одна условная ветвь в середине, что, я думаю, означает, что нельзя использовать векторные операции SIMD, если я не что-то упустил?

1 Ответ

3 голосов
/ 19 апреля 2019

Полагаю, вы думаете о реализациях сложения и вычитания, например:

# Dekker add2
function +{T}(x::Double{T}, y::Double{T})
    r = x.hi + y.hi
    s = abs(x.hi) > abs(y.hi) ? (((x.hi - r) + y.hi) + y.lo) + x.lo : (((y.hi - r) + x.hi) + x.lo) + y.lo
    Double(r, s)
end

В некоторых архитектурах решение может состоять в том, чтобы вычислить обе ветви параллельно, используя инструкции SIMD, а затем выполнитьоперация, которая будет получать правильный результат двух.Например, неправильный результат, полученный путем вычитания x.hi + y.hi из неправильного операнда, всегда может иметь отрицательный знак, поэтому взятие максимума всегда может извлечь правильный результат.(В это время ночи я не буду гарантировать, что это действительно в этом случае, но для некоторых операций общий подход будет такой.)

Другой способ - сравнить вектор {x.hi, y.hi} > {y.hi, x.hi} по порядку.сформировать битовую маску.(Это псевдокод, а не синтаксис Джулии.) Побитовое И битовой маски и пара потенциальных результатов оставят корректный результат без изменений и установят все биты неправильной единицы в ноль.Затем уменьшение маскированного вектора с помощью побитового ИЛИ дает правильный результат.Никакая ветвь не требуется.

У данного ISA могут быть другие приемы, такие как условные инструкции.Или есть другие алгоритмы, чем у Деккера.

...