Привет. Вопрос собственно немного абстрактный. Имеет ли смысл использовать fixed point для вычислений (в смысле скорости). Ясно что для систем где нет fpu выбора особо и нет. Интересует для x86. Будет ли вычисление с помощью SSE быстрее fixed pint (тут думаю да). И особенно интересно будет ли вычисление с помощью fpu быстрее fixed point. Померять то можно, но процессоры разные бывают...
Fixed point - по сути своей костыли, на которые опирались при необходимости нецелочисленных вычислений в эпоху господства машин без сопра. Там были алгоритмы, реализующие всю эту петрушку на программном уровне. FPU же - это уровень аппаратный. И даже несмотря на то, что вычисления с плавающей точкой по определению медленнее, поддержка отдельного модуля для таких вычислений, не нагруженного кучей другой работы, как например CPU, однозначно говорит против fixed'a.
Почему "однозначно"? Не так уж и мало случаев, когда вычисления с фиксированной точкой позволяют достичь заданную точность, при этом они существенно быстрее. Другое дело, что вычисления с плавающей точкой проще, и там не надо задумываться о точности, переполнении и прочих нюансах.
А ведь вы правы. Просто я говорил про некий абстрактный "общий случай". Если автор озвучит конкретную задачу, можно будет оценить, пригодится ли там Fixed-point или нет...
cppasm Ответ стандартный - зависит от алгоритма. Есть алгоритмы, которые выполняют итерации на матрицах/векторах, есть алгоритмы, в которых одной-двух итераций гарантированно хватает для достижения требуемой точности.. Смотря что и как вычисляешь.
Целочисленные cложения\вычитания и особенно сравнения конечно работают существенно быстрее чем float. Скорость умножения примерно одинакова, за исключением P4, где умножение вещественных даже быстрее чем целых. Ну а целочисленное деление на всех процах медленнее, чем вещественное той же точности. Поэтому все зависит от задачи PS: fadd\fsub имеют приличную латентность 3-5 тактов, но они полностью конвееризованы (througput = 1), поэтому возможна организация параллельных вычислений над независимыми данными. Например, неоптимизированное вычисление отдельно суммы элементов массива, отдельно суммы квадратов и того и другого одновременно выполняется за одно время, т.к. тут основным тормозом является большая латентость fadd. Соответственно замена простого подсчета суммы на параллельное вычисление 2 или 4 частичных сумм дает существенный выигрыш в скорости
Тогда вопрос такой: а при работе с 3d под ДОС, где достаточно большое кол-во дискретных величин, не быстрее ли выйдет работа с Fixed Point 16:16, чем с FPU? Я пробовал... у меня на фиксах быстрее раз в 5 (имеется ввиду без оптимизации в обоих случаях). Поэтому щас думаю оставить фиксы или все таки выжать максимум из FPU?
Aloner ИМХО, в этом случае нужно упирать именно на оптимизацию fixed-ов. Чисто по принципу совместимости. Ибо DOS это такая система, которая может работать и на процах, в которых FPU вообще не предусмотрен... +)
Aloner Если используются преимущественно одни сложения\вычитания, то целые числа ес-но будут быстрее "раз в 5". И даже если перемножать матрицы, где вроде бы поровну сложений и умножений, то при реализации в лоб целые числа тоже будут быстрее, т.к. умножения независимы, а сложение перемноженных элементов зависимое и на фпу выполняется в несколько раз медленне. Но если сделать параллельное накопление нескольких сумм, то скорость фпу приблизиться к целочисленному, т.к. у целочисленных резерва ускорения нет (определяется темпом 1 умножение за такт), а в фпу есть - в идеале до 1 умнож. и 1 сложения за такт (зависит от проца)
Есть такие системы и сейчас - и больше чем можно подумать Например те же цифровые фотоаппараты - в большинстве fpu нет. Собственно вопрос не в том зачем придумали fixed point. Уточняю вопрос. Речь идёт про выполнение 2D IDCT 8x8. В основном умножения и сложения, плюс выборка косинусов из таблицы. В обоих случаях как с fixed point так и с floating point требуемая точность достижима. Вопрос только что будет быстрее. Fixed point - 24.8 Циклы разворачивать?
Leo Умножения, деления, сложения, вычитания... А как насчет округления (типа TRUNC и FRAC) ??? На фиксах имхо одним сдвигом делается (для форамата 24:8, для 16:16 - еще проще - для дробной части AX ), а как на FPU (при моих сравнениях получалось в разы медленее на FPU, но эт может конечно из-за кривизны рук %) )? А при работе с графикой приходиться округлять, так как экранные координаты дискретны (представленны целыми числами).
cppasm Ну насчет 8 ты ес-но загнул - регистров не хватит Для скрытия латентности fadd\fsub достаточно разворота на 4 Aloner А как округляешь ? Случаем не через тормозную frndint. Округление рекомендуется делать непосредственно при сохранении числа в целочисленном формате командой fist(p). Латентность у нее приличная, но throughput=1 (в P4 до 2-3), поэтому в потоке команд fist могут выполняться с перекрытием и существенно тормозить не должны, если конечно не нужно сразу читать результат сохранения. С нахождением дробной части конечно проблема, т.к.тут "во всей красе" проявляется латентность frndint или fist. Хотя не очень понятно зачем тебе отдельно нужны добные части ?
Leo Ну хотя бы при программной билинейнной фильтрации текстуры, как во многих досовских тридэшных движках. Может не актуально конечно на сегодняшний день %).
Кстати, мож знает кто-нить какой нить способ возведения Fixed point в квадрат быстрей, чем при умножении числа на само себя ?
А вообще такие способы есть ? На атлонах и P6 умножение выполняется за 3-4 такта - врядли можно придумать что-то быстрее для произволных чисел (только умножения на некоторые константы имеет смысл заменять на lea\shl и т.п.). А под тормозные P4 не имеет смысл особо оптимизировать, т.к. дни их уже сочтены
Я понимаю что умножение и так быстрое... и таблица не поможет тоже... эх... если бы за такт %)) Надыбать бы где нить побольше материала про реализацию математики для фиксов. Мож кто поделиться инфой/ссылками?
Aloner: И таблица квадратов не поможет?? Ну, не знаю тогда.. Остаётся максимально поднимать возможность распараллеливания и искать узкие места в других частях алгоритма: рендеринг обычно много чего лишнего просчитывает.
А чего его вычислять -- индекс в таблице (операнд, параметр "функции") и так является относительным адресом значения. Вообще, можно взять любую удобную (и быструю) команду и построить таблицу под неё. Например, чтобы сегментный регистр задавал параметр, а при подстановке его в адрес получалось значение