|
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
|
|
|
|
|
Nov 19 2013, 13:55
|
Знающий
   
Группа: Свой
Сообщений: 549
Регистрация: 13-07-10
Из: Солнечногорск-7
Пользователь №: 58 414

|
Цитата(DASM @ Nov 19 2013, 14:43)  ARM разные бывают, стоит уточнить. У ARMv6 хардворный дабл есть. Кажется, мы говорим о разных вещах: Вы о наличии ППЗ, обрабатывающего не только 32-разрядные, но и 64-разрядные вещественные числа, а я -- о программной реализации вещественной арифметики с помощью команд обработки целых чисел, т.е. без ППЗ. Для того, чтобы выполнить умножение мантисс вещественных чисел двойной точности, требуется команда умножения, операндами которой являются 64-разрядные числа. Реально мантисса, конечно, меньше -- если память не изменяет, 52 бита -- но в любом случае 32-разрядное умножение здесь не годится, а команд, умножающих более крупные целые числа, ни у каких ARMов нет.
|
|
|
|
|
Nov 20 2013, 05:35
|
Знающий
   
Группа: Свой
Сообщений: 549
Регистрация: 13-07-10
Из: Солнечногорск-7
Пользователь №: 58 414

|
В третий раз повторяю: изучите матчасть, а заодно и математику. Никакого "флотовского умножителя" в природе не существует. Для выполнения операций с вещественными числами используются схемы сложения, умножения, деления и сдвига целых чисел, не имеющие никаких принципиальных отличий от аналогичных узлов, предназначенных для выполнения целочисленной арифметики. Более того, разрядность у вычислительных блоков ППЗ, поддерживающего лишь вещественную арифметику одинарной точности, меньше, чем у аналогичных блоков основного процессора. Например, обычный целочисленный умножитель в основном процессоре позволяет умножить два 32-разрядных целых числа с получением 64-разрядного результата, а пресловутый умножитель в ППЗ, который никакой не "флотовый", а опять-таки самый что ни на есть обычный целочисленный -- лишь два 24-разрядных целых числа (поскольку мантисса вещественных чисел одинарной точности содержит 24 бита). То же самое относится и к другим схемам.
Может быть, теоретически удалось бы извернуться и использовать ППЗ одинарной точности для обработки чисел двойной точности, вот только реализация всего этого будет принципиально такой же, как на целочисленном процессоре без всякого ППЗ, только намного более муторной. Например, для умножения кусков мантисс вещественных чисел двойной точности (размер 53 бита) в любом случае придётся мантиссы разбивать на части и выполнять умножение по кусочкам, а потом складывать промежуточные результаты. На 32-разрядном умножителе основного процессора потребуется 4 операции умножения (32*32 бита с 64-разрядным результатом), а на 24-разрядном умножителе ППЗ -- целых 25 (12*12 бит с 24-разрядным результатом), т.е. даже по одному умножению ППЗ будет проигрывать основному процессору более чем в шесть раз. А ведь требуются ещё сдвиги и сложения, которые на ППЗ реализовать тоже сложней, чем на основном процессоре (если вообще удастся такое сделать -- тут надо думать). Так что такая реализация арифметики двойной точности на ППЗ одинарной точности будет во много медленней, чем её реализация на основном процессоре -- и, что весьма интересно, при этом никакие "плавающие" возможности ППЗ реально использовать невозможно, они лишь мешают.
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|