|
Float-ядро для double операций, Как использовать Float-ядро для double операций |
|
|
|
Nov 16 2013, 11:18
|
Участник

Группа: Участник
Сообщений: 45
Регистрация: 5-06-07
Пользователь №: 28 207

|
Ожидаем поставку процессора с ядром Cortex-M4F с аппаратно реализованными операциями с плавающей точкой (32-битные float).
Точности float для некоторых наших вычислений недостаточно, приходится использовать 64-битный double.
Вопрос - есть ли способ использовать float-сопроцессор для операций формата double? Хотя бы для самых простых - сложение и вычитание?
|
|
|
|
|
Nov 16 2013, 17:25
|
Участник

Группа: Участник
Сообщений: 26
Регистрация: 16-08-13
Из: Ставрополь
Пользователь №: 77 934

|
Цитата(AlexeyT @ Nov 16 2013, 15:18)  Вопрос - есть ли способ использовать float-сопроцессор для операций формата double? Хотя бы для самых простых - сложение и вычитание? Если не смутит ссылка на Хабр, то здесь достаточно подробно описаны внутренности чисел с плавающей точкой, и сразу станет ясно, отчего более короткие float не удастся приспособить под работу с double, которые длиннее их.
|
|
|
|
|
Nov 17 2013, 07:14
|
Участник

Группа: Участник
Сообщений: 45
Регистрация: 5-06-07
Пользователь №: 28 207

|
Цитата(vlad_new @ Nov 17 2013, 06:01)  А я не знал что незяяяяя. Взял и включил сопр. В итоге на флоатах скорость поднялась в 12-15 раз, а на дублях в 3-4.  Эвона как! А ассемблерный листинг можете выложить? Допустим, ассемблерная реализация: double a=2.123456789012345, b=-5.123456789012345, res; res = a+b; в двух вариантах - при включенном и выключенном сопроцессоре. Меня вот никак не отпускает ощущение, что ДОЛЖНО float ядро хоть как-то ускорять операции double.
|
|
|
|
|
Nov 17 2013, 14:48
|
Местный
  
Группа: Участник
Сообщений: 218
Регистрация: 24-06-10
Пользователь №: 58 127

|
Цитата(AlexeyT @ Nov 17 2013, 11:14)  Эвона как! А ассемблерный листинг можете выложить? Допустим, ассемблерная реализация:
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 раза. Так что народ прав. В чистом виде для дубля сопр бесполезен. Но при грамотном смешевании дубля и флоута эффект будет.
|
|
|
|
|
Nov 18 2013, 06:37
|
Знающий
   
Группа: Свой
Сообщений: 549
Регистрация: 13-07-10
Из: Солнечногорск-7
Пользователь №: 58 414

|
Как видим, для деления вызывается подпрограмма, что и следовало ожидать: не может 32-разрядный ППЗ выполнять 64-разрядные операции. Ускорение же, возможно, произошло не только из-за смеси операций (32- и 64-разрядных), но и из-за повышения частоты процессора, если тестирование без ППЗ производилось на физически другом процессоре. Например, если ядро Cortex-M3 (без ППЗ) работало на частоте 60 МГц, а ядро Cortex-M4F (с ППЗ) -- на 180 МГц, то последнее, грубо говоря, будет в 3 раза быстрее на любых операциях именно за счёт роста частоты. Цитата(AlexeyT @ Nov 17 2013, 11:14)  Меня вот никак не отпускает ощущение, что ДОЛЖНО float ядро хоть как-то ускорять операции double. Ну, потратьте время на изучение матчасти -- и тогда поймёте, что никак оно не ускорит и не может ускорить в принципе.
Сообщение отредактировал SII - Nov 18 2013, 06:35
|
|
|
|
|
Nov 18 2013, 19:37
|
Участник

Группа: Участник
Сообщений: 45
Регистрация: 5-06-07
Пользователь №: 28 207

|
Цитата(etoja @ Nov 18 2013, 16:19)  Вы в своём алгоритме скобки правильно расставьте и иногда масштабирование делайте. Так работают алгоритмы цифровой обработки сигналов . Разрешите не понять? Цитата(Golikov A. @ Nov 18 2013, 21:33)  число дабл - это мантисса + порядок. если его разложить на 2 числа
младшая часть мантисы и порядок и старшая часть мантисы и увеличенный порядок
то есть как бы число и уточнение, это позволит уменьшить длину мантисы
далее полученные числа представить в виде флотов, перемножить их, а потом собрать даблы обратно (что собственно и делается в подпрограмме перемножения даблов), то естественно для процессора с поддержкой плавающей точки и умножителем флотов будет выигрыш и в случае перемножения даблов.
я в чем то не прав? Во-во! Вот и я надеялся найти подсказку по алгоритму представления double числа в виде какой-то комбинации двух float. Как, например, операции для __int64 представляются в виде комбинаций обычных 32-битных int.
Сообщение отредактировал AlexeyT - Nov 18 2013, 19:42
|
|
|
|
|
Nov 19 2013, 08:50
|
Гуру
     
Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713

|
Цитата(Golikov A. @ Nov 19 2013, 14:32)  ну вот так как-то (А+B ) * (D + C) = AD + BD + AC + BC с этим я надеюсь все согласятся Не согласятся. У вас число в экспоненциальной форме - это не умножение, а возведение в степень. ну-ка разложите: Код (A+B)^(N+M) (где: ^ - операция возвдения в степень) в сумму PS: Да и поймите - даже если вы найдёте способ, то это будет soft-преобразование double->float, потом будет float операция (или несколько) и обратное soft-преобразование float->double. У вас всё равно 2 операции с double с soft-эмуляцией. Однозначно это будет медленее чем одна операция с double с soft-эмуляцией.
|
|
|
|
|
Nov 19 2013, 10:18
|
Знающий
   
Группа: Свой
Сообщений: 549
Регистрация: 13-07-10
Из: Солнечногорск-7
Пользователь №: 58 414

|
Цитата(Golikov A. @ Nov 19 2013, 12:32)  ну вот так как-то Ещё раз: изучите матчасть. А заодно повторите школьный курс математики, чтобы вспомнить, что такое экспоненциальное представление чисел. Цитата(jcxz @ Nov 19 2013, 12:50)  ну-ка разложите: Код (A+B)^(N+M) (где: ^ - операция возвдения в степень) в сумму У Вас описка: поскольку речь идёт об умножении, то Код A^N * B^M = (A*B)^(N+M) Впрочем, сути дела это не меняет. Для тех, кому всё ещё непонятно: при выполнении умножения чисел с плавающей запятой их мантиссы перемножаются, а порядки -- складываются. Чтобы выполнить умножение мантисс, умножитель должен обладать соответствующей разрядностью, ну а ППЗ, предназначенный для обработки лишь чисел одинарной точности, никак не сможет умножить мантиссы чисел с двойной точности: у него банально не хватит разрядности. Кстати говоря, то же самое относится к программной реализации операций с плавающей запятой: если для перемножения мантисс чисел одинарной точности достаточно лишь одной инструкции 32-разрядного целочисленного умножения, которая у ARMов есть, то для перемножения мантисс чисел двойной точности подходящей инструкции уже нет, и приходится выполнять умножение кусками, суммируя частичные произведения. В общем, наличие ППЗ одинарной точности абсолютно бесполезно, если необходимо выполнять вычисления с двойной точностью: он не может помочь ничем.
Сообщение отредактировал SII - Nov 19 2013, 10:19
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|