Jump to content

    

Float-ядро для double операций

Ожидаем поставку процессора с ядром Cortex-M4F с аппаратно реализованными операциями с плавающей точкой (32-битные float).

 

Точности float для некоторых наших вычислений недостаточно, приходится использовать 64-битный double.

 

Вопрос - есть ли способ использовать float-сопроцессор для операций формата double? Хотя бы для самых простых - сложение и вычитание?

 

Share this post


Link to post
Share on other sites
Вопрос - есть ли способ использовать float-сопроцессор для операций формата double? Хотя бы для самых простых - сложение и вычитание?

Нет.

Share this post


Link to post
Share on other sites
Вопрос - есть ли способ использовать float-сопроцессор для операций формата double? Хотя бы для самых простых - сложение и вычитание?
Если не смутит ссылка на Хабр, то здесь достаточно подробно описаны внутренности чисел с плавающей точкой, и сразу станет ясно, отчего более короткие float не удастся приспособить под работу с double, которые длиннее их.

Share this post


Link to post
Share on other sites
Вопрос - есть ли способ использовать float-сопроцессор для операций формата double? Хотя бы для самых простых - сложение и вычитание?

 

Для только сложения и вычитания проще использовать long long. Без всяких float/double. Как бы значащих цифр больше, чем в double.

Share this post


Link to post
Share on other sites

А я не знал что незяяяяя. Взял и включил сопр. В итоге на флоатах скорость поднялась в 12-15 раз, а на дублях в 3-4. :)

Share this post


Link to post
Share on other sites
А я не знал что незяяяяя. Взял и включил сопр. В итоге на флоатах скорость поднялась в 12-15 раз, а на дублях в 3-4. :)

 

 

Эвона как! А ассемблерный листинг можете выложить? Допустим, ассемблерная реализация:

 

double a=2.123456789012345, b=-5.123456789012345, res; res = a+b;

 

в двух вариантах - при включенном и выключенном сопроцессоре.

Меня вот никак не отпускает ощущение, что ДОЛЖНО float ядро хоть как-то ускорять операции double.

Share this post


Link to post
Share on other sites
Эвона как! А ассемблерный листинг можете выложить? Допустим, ассемблерная реализация:

 

double a=2.123456789012345, b=-5.123456789012345, res; res = a+b;

 

в двух вариантах - при включенном и выключенном сопроцессоре.

Меня вот никак не отпускает ощущение, что ДОЛЖНО float ядро хоть как-то ускорять операции double.

//----------------------FPU OFF ----------------------------------------//

0x08000512 4E93      LDR           r6,[pc,#588] ; @0x08000760
0x08000514 6AB2      LDR           r2,[r6,#0x28]
0x08000516 6AF3      LDR           r3,[r6,#0x2C]
0x08000518 6A30      LDR           r0,[r6,#0x20]
0x0800051A 6A71      LDR           r1,[r6,#0x24]
0x0800051C F003F89B  BL.W          __aeabi_dadd (0x08003656)
0x08000520 6330      STR           r0,[r6,#0x30]
0x08000522 6371      STR           r1,[r6,#0x34]

//----------------------FPU ON -----------------------------------------//
0x08000522 4D94      LDR           r5,[pc,#592] ; @0x08000774
0x08000524 ED950B0A  VLDR          d0,[r5,#0x28]
0x08000528 EC532B10  VMOV          r2,r3,d0
0x0800052C ED950B08  VLDR          d0,[r5,#0x20]
0x08000530 EC510B10  VMOV          r0,r1,d0
0x08000534 F003F841  BL.W          __aeabi_dadd (0x080035BA)
0x08000538 EC410B10  VMOV          d0,r0,r1
0x0800053C ED850B0C  VSTR          d0,[r5,#0x30]

 

Вот пришлось посидеть и понять почему у меня ускорение произошло. Просто у меня кучка всякой математики и некоторые ее части производились во флоуте ( ну где дубль не нужен был),

вот поэтому прога и ускорилась в 3-4 раза. Так что народ прав. В чистом виде для дубля сопр бесполезен. Но при грамотном смешевании дубля и флоута эффект будет.

 

 

Share this post


Link to post
Share on other sites

Как видим, для деления вызывается подпрограмма, что и следовало ожидать: не может 32-разрядный ППЗ выполнять 64-разрядные операции. Ускорение же, возможно, произошло не только из-за смеси операций (32- и 64-разрядных), но и из-за повышения частоты процессора, если тестирование без ППЗ производилось на физически другом процессоре. Например, если ядро Cortex-M3 (без ППЗ) работало на частоте 60 МГц, а ядро Cortex-M4F (с ППЗ) -- на 180 МГц, то последнее, грубо говоря, будет в 3 раза быстрее на любых операциях именно за счёт роста частоты.

 

Меня вот никак не отпускает ощущение, что ДОЛЖНО float ядро хоть как-то ускорять операции double.

 

Ну, потратьте время на изучение матчасти -- и тогда поймёте, что никак оно не ускорит и не может ускорить в принципе.

Edited by SII

Share this post


Link to post
Share on other sites
Ожидаем поставку процессора с ядром Cortex-M4F с аппаратно реализованными операциями с плавающей точкой (32-битные float).

 

Странно. STM32F415, STM32F303 без очереди везде.

 

Вы в своём алгоритме скобки правильно расставьте и иногда масштабирование делайте. Так работают алгоритмы цифровой обработки сигналов .

Возможно компилятор gcc часть этой работы сделает и сам при включенной оптимизации.

Share this post


Link to post
Share on other sites

число дабл - это мантисса + порядок.

если его разложить на 2 числа

 

младшая часть мантисы и порядок

и старшая часть мантисы и увеличенный порядок

 

то есть как бы число и уточнение, это позволит уменьшить длину мантисы

 

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

 

я в чем то не прав?

 

 

Share this post


Link to post
Share on other sites
Вы в своём алгоритме скобки правильно расставьте и иногда масштабирование делайте. Так работают алгоритмы цифровой обработки сигналов .

 

Разрешите не понять?

 

 

 

число дабл - это мантисса + порядок.

если его разложить на 2 числа

 

младшая часть мантисы и порядок

и старшая часть мантисы и увеличенный порядок

 

то есть как бы число и уточнение, это позволит уменьшить длину мантисы

 

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

 

я в чем то не прав?

 

 

Во-во! Вот и я надеялся найти подсказку по алгоритму представления double числа в виде какой-то комбинации двух float. Как, например, операции для __int64 представляются в виде комбинаций обычных 32-битных int.

Edited by AlexeyT

Share this post


Link to post
Share on other sites
я в чем то не прав?

В математике.

То что Вы сказали, переведите на математический язык (формулами).

И поймёте почему.

Share this post


Link to post
Share on other sites

ну вот так как-то

(А+B ) * (D + C) = AD + BD + AC + BC

с этим я надеюсь все согласятся

 

 

далее мне кажется что число вида (для простоты будем оперировать целыми)

11112222 всегда можно представить в виде 1111 * 10000 + 2222

 

(A*B *C * D) == A*C*B*D

 

если число вида 1111 * 10000 считать А = 1111, B = 10000, то мы получаем

арифметику с числами 1111 2222 - половинного порядка, и выравнивание порядков и суммирование

 

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

Share this post


Link to post
Share on other sites
ну вот так как-то

(А+B ) * (D + C) = AD + BD + AC + BC

с этим я надеюсь все согласятся

Не согласятся.

У вас число в экспоненциальной форме - это не умножение, а возведение в степень.

ну-ка разложите:

(A+B)^(N+M)

(где: ^ - операция возвдения в степень) в сумму

 

PS: Да и поймите - даже если вы найдёте способ, то это будет soft-преобразование double->float, потом будет float операция (или несколько) и обратное soft-преобразование float->double.

У вас всё равно 2 операции с double с soft-эмуляцией. Однозначно это будет медленее чем одна операция с double с soft-эмуляцией.

Share this post


Link to post
Share on other sites
ну вот так как-то

 

Ещё раз: изучите матчасть. А заодно повторите школьный курс математики, чтобы вспомнить, что такое экспоненциальное представление чисел.

 

ну-ка разложите:
(A+B)^(N+M)

(где: ^ - операция возвдения в степень) в сумму

 

У Вас описка: поскольку речь идёт об умножении, то

A^N * B^M = (A*B)^(N+M)

Впрочем, сути дела это не меняет.

 

Для тех, кому всё ещё непонятно: при выполнении умножения чисел с плавающей запятой их мантиссы перемножаются, а порядки -- складываются. Чтобы выполнить умножение мантисс, умножитель должен обладать соответствующей разрядностью, ну а ППЗ, предназначенный для обработки лишь чисел одинарной точности, никак не сможет умножить мантиссы чисел с двойной точности: у него банально не хватит разрядности. Кстати говоря, то же самое относится к программной реализации операций с плавающей запятой: если для перемножения мантисс чисел одинарной точности достаточно лишь одной инструкции 32-разрядного целочисленного умножения, которая у ARMов есть, то для перемножения мантисс чисел двойной точности подходящей инструкции уже нет, и приходится выполнять умножение кусками, суммируя частичные произведения.

 

В общем, наличие ППЗ одинарной точности абсолютно бесполезно, если необходимо выполнять вычисления с двойной точностью: он не может помочь ничем.

Edited by SII

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this