Хабрахабр

И все-таки, почему Posit являются достойной альтернативой IEEE 754

Месяц Posit объявлен на Хабре открытым, а значит я не могу пройти мимо и проигнорировать обрушившуюся на них критику. В предыдущих сериях:

Часть 1
Posit-арифметика: победа над floating point на его собственном поле. Новый подход может помочь нам избавиться от вычислений с плавающей запятой
Posit-арифметика: победа над floating point на его собственном поле. Часть 2
Испытания Posit по-взрослому

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

В данной статье я попытаюсь объяснить почему. Именно с таким неприятием на сегодняшний день сталкивается формат Posit: критикующие зачастую просто “не туда смотрят“ и даже банально неправильно используют Posit в своих экспериментах.

Не мало было высказано и критики: никудышная точность для очень больших или очень маленьких значений, сложный формат бинарного представления и конечно отсутствие аппаратной поддержки. О достоинствах Posit было сказано уже не мало: математическая элегантность, высокая точность на значениях с низкой экспонентой, широкий диапазон значений, только одно бинарное представление NaN и нуля, отсутствие субнормальных значений, борьба с overflow/underflow.

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

Правила игры изменились

Стандарт IEEE 754 описывает числа с плавающей запятой, реализованный в Intel 8087 почти 40 лет назад. По меркам нашей индустрии это невероятный срок; с тех пор изменилось практически все: производительность процессоров, стоимость памяти, объемы данных и масштабы вычислений. Формат Posit был разработан не просто как лучшая версия IEEE 754, а как подход к работе с числами, отвечающий новым требованиям времени.

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

40 лет назад производительность компьютеров почти полностью зависела от производительности процессора. Во-первых, изменились приоритеты для оптимизации. Чтобы убедится в этом, достаточно взглянуть на ключевые направления развития процессоров последних десятилетий: трёхуровневое кеширование, спекулятивное выполнение, конвейеризация вычислений, предсказывание ветвлений. Сегодня производительность большинства вычислений упираются в память. Все эти подходы направлены на достижение высокой производительности в условиях быстрых вычислений и медленного доступа к памяти.

image

За последние десятилетия технологии горизонтального масштабирования вычислений продвинулись вперед настолько, что нас начала волновать не столько скорость этих вычислений, сколько счет за электричество. Во-вторых, на первый план вышло новое требование – эффективное энергопотребление. С точки зрения энергоэффективности вычисления стоят дешево, ведь регистры процессора находятся очень близко к его вычислителям. Здесь мне следует подчеркнуть важную для понимания деталь. Гораздо дороже прийдется расплачиваться за передачу данных, как между процессором и памятью (x100), так и на дальние расстояния (x1000...).

image

Вот лишь один из примеров научного проекта, который планирует использовать Posit:

image

Очевидно, что для таких проектов сокращение объемов данных и энергопотребления является критическим. Эта сеть телескопов генерирует 200 петабайт данных в секунду, на обработку которых уходит мощность небольшой электростанции – 10 мегаватт.

В самое начало

Так что же предлагает стандарт Posit? Чтобы понять это, нужно вернуться в самое начало рассуждений и понять, что подразумевается под точностью чисел с плавающей запятой.

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

Posit – это в первую очередь формат представления рациональных чисел, а не способ выполнения операций над ними. Другими словами, Posit – это формат сжатия рациональных чисел с потерями. Теперь будет важный для осознания момент. Так вот, речь идет именно о сокращении необходимого объема данных в два раза для хранения и передачи одного и того же набора чисел. Вы могли слышать утверждение, что 32-битные Posit – это хорошая альтернатива 64-битным Float. В два раза меньше памяти – почти в 2 раза меньше энергопотребления и высокая производительность процессора благодаря меньшим ожиданиям доступа к памяти.

Второй конец палки

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

Это другой формат представления рациональных чисел, неразрывно связанный с Posit. На самом деле, способ выполнения точных вычислений есть, и он называется Quire. В отличии от Posit, формат Quire предназначен именно для вычислений и для хранения промежуточных значений в регистрах, а не в основной памяти.

image

Единице, как бинарному представлению Quire соответствует минимальное положительное значение Posit. Если в вкратце, то Quire представляют из себя не что иное, как широкий целочисленный аккумулятор (fixed point arithmetic). Каждое значение Posit имеет однозначное представление в Quire без потери точности, но не каждое значение Quire может быть представлено в Posit без потери точности. Максимальное значение Quire соответствует максимальному значению Posit.

Они позволяют выполнять операции с несравнимо более высокой точностью чем Float, а для операций сложения и умножения какой-либо потери точности не будет вообще. Цена, которую за это приходится платить – широкие регистры процессора (32-битным Posit с es=2 соответствуют 512-битные Quire), но для современных процессоров это не является серьезной проблемой. Преимущества Quire очевидны. И если 40 лет назад вычисления над 512 битными целыми числами казались неприемлемой роскошью, то сегодня это является скорее адекватной альтернативой широкому доступу к памяти.

Собираем пазл

Таким образом, Posit предлагают не просто новый стандарт в виде альтернативы Float/Double, а скорее новый подход по работе с числами. В отличии от Float – который является единым представлением, пытающимся найти компромис между и точностью, и эффективностью хранения, и эффективностью вычислений, Posit предлагает использовать два различных формата представления, один для хранения и передачи чисел – собственно Posit, и другой для вычислений и их промежуточных значений – Quire.

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

  1. Прочитать значения чисел из памяти.
  2. Выполнить некоторую последовательность операций. Иногда количество операций является достаточно большим. При этом, все промежуточные значения вычислений хранятся в регистрах.
  3. Записать результат операций в память.

В случае применения Posit+Quire потеря точности во время вычислений ничтожна. В случае применения Float/Double точность теряется на каждой операции. Именно по-этому большинство проблем “накопления ошибки” для Posit+Quire просто не актуальны. Она теряется только на последнем этапе, в момент преобразования значения Quire в Posit.

Как результат – более быстрый доступ к данным из памяти (лучше производительность) и более эффективное хранение и передача информации. В отличии от Float/Double, при применения Posit+Quire мы как правило можем позволить себе более компактное представления чисел.

Соотношение Мюллера

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

image

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

Вычисления проводились в арифметике Quire, но каждое значение в таблице преобразовано в Posit. Я провел эксперимент для IEEE 754 с одинарной и двойной точностью, а также для 32-битных Posit+Quire.

Результаты эксперимента

# float(32) double(64) posit(32)
------------------------------------------------ 0 4.000000 4.000000 4 1 4.250000 4.250000 4.25 2 4.470589 4.470588 4.470588237047195 3 4.644745 4.644737 4.644736856222153 4 4.770706 4.770538 4.770538240671158 5 4.859215 4.855701 4.855700701475143 6 4.983124 4.910847 4.91084748506546 7 6.395432 4.945537 4.94553741812706 8 27.632629 4.966962 4.966962575912476 9 86.993759 4.980042 4.980045706033707
10 99.255508 4.987909 4.98797944188118
11 99.962585 4.991363 4.992770284414291
12 99.998131 4.967455 4.99565589427948
13 99.999908 4.429690 4.997391253709793
14 100.000000 -7.817237 4.998433947563171
15 100.000000 168.939168 4.9990600645542145
16 100.000000 102.039963 4.999435931444168
17 100.000000 100.099948 4.999661535024643
18 100.000000 100.004992 4.999796897172928
19 100.000000 100.000250 4.999878138303757
20 100.000000 100.000012 4.999926865100861
21 100.000000 100.000001 4.999956130981445
22 100.000000 100.000000 4.999973684549332
23 100.000000 100.000000 4.9999842047691345
24 100.000000 100.000000 4.999990522861481
25 100.000000 100.000000 4.999994307756424
26 100.000000 100.000000 4.999996602535248
27 100.000000 100.000000 4.999997943639755
28 100.000000 100.000000 4.999998778104782
29 100.000000 100.000000 4.99999925494194
30 100.000000 100.000000 4.999999552965164
31 100.000000 100.000000 4.9999997317790985
32 100.000000 100.000000 4.999999850988388
33 100.000000 100.000000 4.999999910593033
34 100.000000 100.000000 4.999999940395355
35 100.000000 100.000000 4.999999970197678
36 100.000000 100.000000 4.999999970197678
37 100.000000 100.000000 5
38 100.000000 100.000000 5
39 100.000000 100.000000 5
40 100.000000 100.000000 5
41 100.000000 100.000000 5
42 100.000000 100.000000 5
43 100.000000 100.000000 5
44 100.000000 100.000000 5
45 100.000000 100.000000 5
46 100.000000 100.000000 5
47 100.000000 100.000000 5
48 100.000000 100.000000 5
49 100.000000 100.000000 5
50 100.000000 100.000000 5
51 100.000000 100.000000 5
52 100.000000 100.000000 5.000000059604645
53 100.000000 100.000000 5.000000983476639
54 100.000000 100.000000 5.000019758939743
55 100.000000 100.000000 5.000394910573959
56 100.000000 100.000000 5.007897764444351
57 100.000000 100.000000 5.157705932855606
58 100.000000 100.000000 8.057676136493683
59 100.000000 100.000000 42.94736957550049
60 100.000000 100.000000 93.35784339904785
61 100.000000 100.000000 99.64426326751709
62 100.000000 100.000000 99.98215007781982
63 100.000000 100.000000 99.99910736083984
64 100.000000 100.000000 99.99995517730713
65 100.000000 100.000000 99.99999809265137
66 100.000000 100.000000 100
67 100.000000 100.000000 100
68 100.000000 100.000000 100
69 100.000000 100.000000 100
70 100.000000 100.000000 100

Как видно из таблицы, 32-битные Float сдаются уже на седьмом значении, а 64-битные Float продержались до 14 итерации. В тоже время, вычисления для Posit с применением Quire возвращают стабильный результат вплоть до 58 итерации!

Мораль

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

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

Когда он утверждает, что новая идея работать не будет — то он, весьма вероятно, ошибается. Ну и не забывайте первый закон Кларка (вольная интерпретация): Когда уважаемый и опытный эксперт утверждает, что новая идея будет работать, то он почти наверняка прав. Ведь дьявол кроется в деталях, и даже опытные люди могут их упустить. Я не считаю себя опытным экспертом, чтобы позволить вам полагаться на мое мнение, но прошу вас с настороженностью относиться к критике даже опытных и уважаемых людей.

Теги
Показать больше

Похожие статьи

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Кнопка «Наверх»
Закрыть