LINUX.ORG.RU

Бинарная совместимость математических операций


0

0

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

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

Под платформой понимается комбинация процессор/компиллятор (операционная система думаю роли не играет). Из списка заявленых платформ можно выделить: x86, x86_64, ppc, ppc_64, GCC 4.x, MSVC 2008. (Компиллятором от Microsoft можно пренебречь в релизе продукта, но для отладочной версии он очень желателен.)

Собственно, в чём заключается конечная задача, чтобы понять весь смысл зачем это нужно:

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

Как это вижу в итоге я (целевой язык C++):

class Float
{
public:
  // other math operations
  static Float sqrt( const Float & f );
  ...
  // common math operations
  Float operator*( const Float & f ) const;
  ...

private:
  <internal representation>
};

То-есть нужно выбрать внутреннее представление для заданного типа (int, long, float point number, fixed point number, etc) и гарантировать что операции на различных платформах дадут один и тот же результат.

Где об этом можно почитать? Какие опции GCC/MSVC существуют для математических операций? Потенциальные грабли? Приветствуются любые замечания.

★★★★★

use Boost.

// takeum

anonymous
()

Мне кажется, что это невозможно: вычисления с плавающей точкой по-определению не абсолютно точные, просто потому, что на разных архитектурах и поколениях процессоров вычисление одних и тех же иррациональных и трасцендентных функций может быть реализовано различным образом. Вообще, не до конца понятна необходимость получения побитово эквивалентного результата: какие-то вычисления проводятся _одновременно_ на нескольких процессорах/системах, а потом результат сравнивается? С какой целью?

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

annoynimous ★★★★★
()
Ответ на: комментарий от annoynimous

> вычисления с плавающей точкой по-определению не абсолютно точные

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

На счёт точности. Погрешность допустима и ей можно пренебречь, выбор типа для того или иного параметра будет осуществлятьсяна основе двух критериев:
1. максимальное значение
2. погрешность каждой из операции над типом

Другими словами погрешность не имеет значения. Главное - чтобы на всех платформах она была одинакова.

> Вообще, не до конца понятна необходимость получения побитово эквивалентного результата


Тонкий игровой сервер. Ближайший пример - BattleNet. Семейство стратегических игр от Blizzard построено именно на протоколе с предсказуемостью вычислений. Огромное количество данных на клиенте, которое нужно обработать, результат вычислений должен совпасть. Переслать такое количество данных по сети невозможно.

Dendy ★★★★★
() автор топика
Ответ на: комментарий от annoynimous

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

Не поэтому. А потому, что точно реализовать вычисления с плавающей точкой невозможно в принципе.

Miguel ★★★★★
()

В жабке есть класс StrictMath. Саны говорят что он разработан так чтобы на всех платформах работать с плавающей точкой одинаково.

Absurd ★★★
()
Ответ на: комментарий от Miguel

> Не поэтому. А потому, что точно реализовать вычисления с плавающей точкой невозможно в принципе.

Это понятно. Как было сказано выше - абсолютная точность и не нужна.

> В жабке есть класс StrictMath. Саны говорят что он разработан так чтобы на всех платформах работать с плавающей точкой одинаково.

Классно. У меня язык разработки - C++, соответственно нужны классы для него. Кто работал с Boost - есть ли в нём классы, удовлетворяющие заявленым требованиям?

Dendy ★★★★★
() автор топика
Ответ на: комментарий от Dendy

> Тонкий игровой сервер.

0. google "deterministic floating point".

1. если не использовать всякие sin, cos, sqrt, ... - то величина погрешности будет близкая.

2. специальные значения (NaN,...) - могут быть разными на разных платформах

3. Обратите внимание, что по дефолту D3D (если под него разрабатываете) переключает приложение в режим с менее точными числами с плавающей точкой (D3DCREATE_FPU_PRESERVE).

stpg
()
Ответ на: комментарий от stpg

> 0. google "deterministic floating point".

Спасибо за буквы, сейчас погуглим.

> 1. если не использовать всякие sin, cos, sqrt, ... - то величина погрешности будет близкая.

Погрешность допустима большая, но не близкая, а абсолютно точная. Тригонометрия нужна.

> 2. специальные значения (NaN,...) - могут быть разными на разных платформах

NaN числа использоваться не планируются. Любая операция, генерирующая такое число, будет расценена как ошибка в вызывающем коде.

> 3. Обратите внимание, что по дефолту D3D (если под него разрабатываете) переключает приложение в режим с менее точными числами с плавающей точкой (D3DCREATE_FPU_PRESERVE).

Бизнесс-логика будет полностью платформонезависима и отвязана от визуального представления. С D3D в связях замечен не был и не планирую.

Dendy ★★★★★
() автор топика
Ответ на: комментарий от stpg

Большое спасибо. Думаю чтива мне хватит чтоб зарыться на неделю (-: В своё время реализовывал то же самое на встроеных типах (float, double). Даже работало. Но сейчас понимаю что нужно делать по уму.

Dendy ★★★★★
() автор топика
Ответ на: комментарий от Dendy

>> В жабке есть класс StrictMath. Саны говорят что он разработан так чтобы на всех платформах работать с плавающей точкой одинаково.

>Классно. У меня язык разработки - C++, соответственно нужны классы для него.

А реализация на Си собственно и написана AFAIK.

Absurd ★★★
()

Мозги не *би. Вычисляй целочисленно.

anonymous
()

> Пример. Есть дробное число, необходимо извлечь из него корень

из рационального числа вообще говоря корень извлечь нельзя (так чтобы не выйти за пределы поля рациональных чисел).

вообще же рациональные числа представляются парами целых, как например в scheme

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.