sab123: (face)
[personal profile] sab123
Навеяло: как известно, плавающие числа нельзя сравнивать на точное равенство. Вместо того их надо сравнивать на различие в пределах погрешности. Спрашивается:

(1) Какого хрена в процессорах нет инструкции сравнения на равенство с погрешностью? которая брала бы три операнда - два числа и размер погрешности. Кстати, ту же фигню можно использовать и для сравнения на больше-меньше, чтобы разница в пределах погрешности считалась равенством.

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

Date: 2014-12-22 06:42 pm (UTC)
spamsink: (Default)
From: [personal profile] spamsink
(1) В процессорах нет инструкции сравнения на равенство с погрешностью ровно потому же, почему нет, скажем, инструкции сложения трех чисел: потому что и то, и другое легко реализуется программно, и экономия времени не будет оправдывать расходы на дополнительные транзисторы, тем более что городить дополнительный data path для третьего операнда гораздо дороже, чем реализовать какую-нибудь команду с двумя операндами.

(2) Это называется "подпрограмма", и существует во всех языках высокого уровня.

Date: 2014-12-22 07:01 pm (UTC)
From: [identity profile] orleanz.livejournal.com
Жестоко слово сие

Date: 2014-12-22 07:45 pm (UTC)
spamsink: (Default)
From: [personal profile] spamsink
Но справедливо. Желание иметь инструкцию с тремя операндами свидетельствует о принципиальном непонимании процессорной архитектуры. Абсолютная погрешность реализуется вычитанием и взятием абсолютной величины - это две очень дешевые операции.

Операция сравнения на равенство с погрешностью на уровне языка - ненужный "синтаксический сахар", и в языках с мощностью, сравнимой с С++, реализуется самостоятельно с тем же успехом.

Date: 2014-12-22 07:50 pm (UTC)
From: [identity profile] sab123.livejournal.com
(1) Делать программно - сложно и медленно. Это как минимум 3 инструкции - вычесть, abs, сравнить. Ну, и если очень хотеть, то ничего не мешает установить третий операнд отдельной командой в регистр состояния, откуда его потом и брать (он скорее всего не будет меняться для многих сравнений). А что касается дополнительных транзисторов, то они нынче фигня, проблема не в том. чтобы наштамповать транзисторов, а в том, чтобы из них извлечь пользу.

(2) Подпрограммой - неудобно. Не говоря уже о том, как неудобно ее увязывать со значением, задаваемым в начале блока. Ну и вообще, в любом случае не подпрограмма, а хотя бы макро.

Date: 2014-12-22 08:06 pm (UTC)
spamsink: (Default)
From: [personal profile] spamsink
1. Чем больше у процессора состояния, тем сложнее переключать контексты.

2. Польза из транзисторов извлекается путем их использования в как можно большем числе команд. Редко используемые команды с уникальной функциональностью - dead weight.

3. Делать программно ровно так же быстро, как и аппаратно. Если процессор в принципе умеет делать операцию, описываемую как "вычесть, abs, сравнить" быстрее, чем за 3 такта, то он это сможет сделать и путем instruction fusion. А если не умеет, то выгоды на копеечной экономии размера кода практически никакой.

Пишешь класс со статическим стеком значений точности и переопределенной операцией сравнения (== подпрограммой). Значение, задаваемое в начале блока, кладется на верхушку стека, в конце блока - убирается оттуда. И все дела.

Date: 2014-12-22 08:41 pm (UTC)
From: [identity profile] sab123.livejournal.com
1. А вот для этого у нас есть компилятор. Можно не сохранять контекст, а просто пусть следит за тем, чтобы заново загрузить контекст между вызовом функции и следующим использованием.

2. Ну так это не редко используемые, а часто используемые команды. Вот точное сравнение - это будут редко используемые, если писать правильно, а не срезать углы.

3. Процессору необязательно выполнять как "вычесть, abs, сравнить", а можно например параллельно выполнить два вычитания и два сравнения. Про instruction fusion - это совершенно та же фигня, по сути одна инструкция, записывающаяся магической последовательностью кодов. Кстати, наверное интересная и разновидность - это брать точность не как константу, а как зависящую от порядка участвующих значений.

4. Это коряво, медленно, и непонятно как реализовать если блоком является класс или файл. Кстати, обрати внимание на то, что генерить правильную магическую последовательность инструкций для instruction fusion без поддержки компилятора не получится. Ну ладно, положим, Си - это не язык, заточенный под плавающую математику, в нем можно обойтись ручными костылями и даже плюнуть на эффективность. Но в языках-то, заточенных под математику, типа Фортрана или SQL - почему нет?
Edited Date: 2014-12-22 08:42 pm (UTC)

Date: 2014-12-22 09:03 pm (UTC)
spamsink: (Default)
From: [personal profile] spamsink
1. Речь о переключении контекстов между независимым процессами.

2. Как часто, вообще, используется в реальных алгоритмах сравнение плавающих чисел на (приближенное) равенство? Конкретные значения есть?
В итеративных алгоритмах epsilon - параметр для условия завершения итераций, поэтому записывать эту единственную проверку и удобнее, и математичнее как abs(x-y) < epsilon.

3. Instruction reordering разберется, точно так же, как разбирается со сложением четырех чисел. И операция должна быть коммутативной, иначе вообще бардак будет.

4. В фортране есть встроенные функции epsilon и tiny, позволяющие более гибко выразить, что хочется. За SQL я не отвечаю. :)

Date: 2014-12-22 09:24 pm (UTC)
From: [identity profile] sab123.livejournal.com
> Речь о переключении контекстов между независимым процессами.
Ну так использовать фиксированный регистр (какой-нибудь %f0 или в этом роде), он сохранится вместе с остальными регистрами плавающей точки. И так же полно инструкций, которые требуют, чтобы один из операндов был в фиксированном регистре.

> Как часто, вообще, используется в реальных алгоритмах сравнение плавающих чисел на (приближенное) равенство? Конкретные значения есть?

Мои лично использования сводятся к аналогу SQL, и там оно нужно просто постоянно. Если делать правильно.

> В итеративных алгоритмах epsilon - параметр для условия завершения итераций, поэтому записывать эту единственную проверку и удобнее, и математичнее как abs(x-y) < epsilon.

А в терминах равенства с погрешностью можно было бы записывать еще проще: x != y.

> В фортране есть встроенные функции epsilon и tiny, позволяющие более гибко выразить, что хочется.

Почитал. Это на самом деле не функции, а константы типа как в limits.h. С которыми надо все равно вручную сравнивать.

Date: 2014-12-22 09:35 pm (UTC)
spamsink: (Default)
From: [personal profile] spamsink
Неортогональные ISAs ужасны.

Зачем в SQL плавающая точка? Значения каких типов предметной области нужно хранить в этом формате?

можно было бы записывать еще проще: x != y

Предварительно выполнив где-то далеко в коде setprecision(epsilon). Текстуальная локальность ухудшается, а с ней и читаемость-поддерживаемость кода.

С которыми надо все равно вручную сравнивать.

Так о том и речь, что иногда надо с epsilon, иногда - c tiny. Чем переключать режимы туда-сюда, проще написать сравнение явно.

Date: 2014-12-22 09:49 pm (UTC)
From: [identity profile] sab123.livejournal.com
> Значения каких типов предметной области нужно хранить в этом формате?

Например, финансовые. Когда речь идет не о точных значениях денег, а о вероятностных оценках и тому подобном.

> Предварительно выполнив где-то далеко в коде setprecision(epsilon). Текстуальная локальность ухудшается, а с ней и читаемость-поддерживаемость кода.

Наборот, читаемость и поддерживаемость увеличивается от того, что код не засоряется повторениями epsilon.

> Так о том и речь, что иногда надо с epsilon, иногда - c tiny. Чем переключать режимы туда-сюда, проще написать сравнение явно.

Гм, а когда с кем из них?

(no subject)

From: [personal profile] spamsink - Date: 2014-12-22 10:06 pm (UTC) - Expand

(no subject)

From: [identity profile] sab123.livejournal.com - Date: 2014-12-22 10:16 pm (UTC) - Expand

(no subject)

From: [personal profile] spamsink - Date: 2014-12-22 10:36 pm (UTC) - Expand

(no subject)

From: [identity profile] sab123.livejournal.com - Date: 2014-12-22 10:44 pm (UTC) - Expand

(no subject)

From: [personal profile] spamsink - Date: 2014-12-22 10:56 pm (UTC) - Expand

(no subject)

From: [identity profile] sab123.livejournal.com - Date: 2014-12-22 11:09 pm (UTC) - Expand

(no subject)

From: [identity profile] sab123.livejournal.com - Date: 2014-12-22 11:04 pm (UTC) - Expand

(no subject)

From: [personal profile] spamsink - Date: 2014-12-22 11:12 pm (UTC) - Expand

(no subject)

From: [identity profile] sab123.livejournal.com - Date: 2014-12-22 11:33 pm (UTC) - Expand

(no subject)

From: [personal profile] spamsink - Date: 2014-12-22 11:41 pm (UTC) - Expand

(no subject)

From: [identity profile] sab123.livejournal.com - Date: 2014-12-22 11:53 pm (UTC) - Expand

(no subject)

From: [personal profile] spamsink - Date: 2014-12-23 12:29 am (UTC) - Expand

(no subject)

From: [identity profile] sab123.livejournal.com - Date: 2014-12-23 12:50 am (UTC) - Expand

(no subject)

From: [personal profile] spamsink - Date: 2014-12-23 12:59 am (UTC) - Expand

(no subject)

From: [identity profile] sab123.livejournal.com - Date: 2014-12-23 01:15 am (UTC) - Expand

(no subject)

From: [personal profile] spamsink - Date: 2014-12-23 01:23 am (UTC) - Expand

(no subject)

From: [identity profile] sab123.livejournal.com - Date: 2014-12-23 01:55 am (UTC) - Expand

(no subject)

From: [personal profile] spamsink - Date: 2014-12-23 02:04 am (UTC) - Expand

(no subject)

From: [identity profile] sab123.livejournal.com - Date: 2014-12-23 04:46 am (UTC) - Expand

(no subject)

From: [personal profile] spamsink - Date: 2014-12-23 04:55 am (UTC) - Expand

(no subject)

From: [identity profile] vit-r.livejournal.com - Date: 2014-12-24 02:54 am (UTC) - Expand

Date: 2014-12-22 07:19 pm (UTC)
From: [identity profile] juan-gandhi.livejournal.com
Очень справедливо.

Date: 2014-12-22 07:46 pm (UTC)
spamsink: (Default)
From: [personal profile] spamsink
Ты серьезно, что ли?

Date: 2014-12-22 07:48 pm (UTC)
From: [identity profile] juan-gandhi.livejournal.com
Да. Если на самом деле равенство не определено, то зачем это расширение алгебры?

Date: 2014-12-22 07:56 pm (UTC)
spamsink: (Default)
From: [personal profile] spamsink
Вот и я говорю, что незачем. Ты на что хотел ответить "справедливо" - на пост или на мой комментарий?

Date: 2014-12-22 08:04 pm (UTC)
From: [identity profile] sab123.livejournal.com
Вот сравнение на точное равенство можно выбросить за бессмыссленностью.

Date: 2014-12-22 08:08 pm (UTC)
spamsink: (Default)
From: [personal profile] spamsink
Не собачье дело языка решать, как и для чего я использую числа с плавающей точкой.

Date: 2014-12-22 08:28 pm (UTC)
From: [identity profile] sab123.livejournal.com
При установке погрешности в 0, операции делаются эквивалентными. И это именно что дело языка - предоставить удобный набор операций, отражающих концепции предметной области.

Если каждый текст про программирование с плавающей точкой начинается с "их нельзя сравнивать", то почему оно не отражено в языках? А потом люди < a href="http://vit-r.livejournal.com/782219.html">предъявляют претензии. Кстати, в SQL и вовсе нет определяемых пользователем подпрограмм.

Date: 2014-12-22 08:35 pm (UTC)
spamsink: (Default)
From: [personal profile] spamsink
Эквивалентными, но более дорогими, чем сейчас. Зачем нам эта головная боль?

набор операций, отражающих концепции предметной области

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

Edited Date: 2014-12-22 08:37 pm (UTC)

(no subject)

From: [identity profile] sab123.livejournal.com - Date: 2014-12-22 08:52 pm (UTC) - Expand

(no subject)

From: [personal profile] spamsink - Date: 2014-12-22 09:08 pm (UTC) - Expand

(no subject)

From: [identity profile] sab123.livejournal.com - Date: 2014-12-22 09:35 pm (UTC) - Expand

(no subject)

From: [personal profile] spamsink - Date: 2014-12-22 09:57 pm (UTC) - Expand

Date: 2014-12-22 09:21 pm (UTC)
From: [identity profile] juan-gandhi.livejournal.com
На пост. Заявление правильное; правильного ответа как-то нету зато.

Date: 2014-12-22 09:30 pm (UTC)
spamsink: (Default)
From: [personal profile] spamsink
Ну так дай его. :)

Date: 2014-12-22 09:36 pm (UTC)
From: [identity profile] juan-gandhi.livejournal.com
Его вообще нету. У меня тоже.
Все сложно. Тут есть хитрая комонада, и традиция такова, что мы не вполне понимаем, что вообще за зверь такой, вещественные числа.

Date: 2014-12-22 09:43 pm (UTC)
From: [identity profile] sab123.livejournal.com
Если вспомнить методички из институтского курса физики, там предлагалось при выполнении каждой операции вычислять погрешность получившегося значения исходя из погрешности операндов и типа операции. То есть, на самом деле каждое число представлялось диапазоном. Для честного вычисления плавающих чисел, видимо, надо делать то же самое. А если подходить еще умнее, то может быть надо даже диапазоном с распределением вероятности в нем, но это может быть уже лишнее с практической точки зрения.
Edited Date: 2014-12-22 09:45 pm (UTC)

(no subject)

From: [personal profile] spamsink - Date: 2014-12-22 09:45 pm (UTC) - Expand

(no subject)

From: [identity profile] sab123.livejournal.com - Date: 2014-12-22 09:58 pm (UTC) - Expand

(no subject)

From: [personal profile] spamsink - Date: 2014-12-22 10:08 pm (UTC) - Expand

Date: 2014-12-22 08:41 pm (UTC)
From: [identity profile] enternet.livejournal.com
Сергей, вы поразительный человек. Оптимист. Даже на вашем юзерпике изображен человек, который пытается задушиться биноклем, но улыбается при этом.

Не могли бы вы уточнить, какие именно числа с плавающей точкой нельзя сравнивать на точное равенство: двоичные или десятичные. И ещё меня смущает понятие погрешности. Думаю что это про грех, грех точного сравнения чисел, какому мы все предаемся.

Извините )

Date: 2014-12-22 08:57 pm (UTC)
From: [identity profile] sab123.livejournal.com
Если я правильно помню (я не настоящий сварщик по преданию греху с плавающими числами, а только по верхушкам нахватался), в общем случае никакие нельзя. Но, конечно, от переводов из десятичных в двоичные и назад добавляется пикантности.

Date: 2014-12-23 02:32 am (UTC)
ext_659893: Sapa (Default)
From: [identity profile] sappa.livejournal.com
Предлагаю вообще выкинуть плавающую точку из интеловских процессоров, кому надо и софтово сэмулируют. А освободившиеся транзисторы занять сопроцессором майнинга биткойнов.

January 2026

S M T W T F S
     12 3
45 6 7 8 9 10
11 12 13 14 151617
1819202122 23 24
25 26 2728293031

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Jan. 28th, 2026 11:47 am
Powered by Dreamwidth Studios