реклама на сайте
подробности

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> Float-ядро для double операций, Как использовать Float-ядро для double операций
AlexeyT
сообщение Nov 16 2013, 11:18
Сообщение #1


Участник
*

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



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

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

Вопрос - есть ли способ использовать float-сопроцессор для операций формата double? Хотя бы для самых простых - сложение и вычитание?
Go to the top of the page
 
+Quote Post
scifi
сообщение Nov 16 2013, 12:18
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(AlexeyT @ Nov 16 2013, 15:18) *
Вопрос - есть ли способ использовать float-сопроцессор для операций формата double? Хотя бы для самых простых - сложение и вычитание?

Нет.
Go to the top of the page
 
+Quote Post
fatlortroll
сообщение Nov 16 2013, 17:25
Сообщение #3


Участник
*

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



Цитата(AlexeyT @ Nov 16 2013, 15:18) *
Вопрос - есть ли способ использовать float-сопроцессор для операций формата double? Хотя бы для самых простых - сложение и вычитание?
Если не смутит ссылка на Хабр, то здесь достаточно подробно описаны внутренности чисел с плавающей точкой, и сразу станет ясно, отчего более короткие float не удастся приспособить под работу с double, которые длиннее их.
Go to the top of the page
 
+Quote Post
Rst7
сообщение Nov 16 2013, 21:51
Сообщение #4


Йа моск ;)
******

Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610



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


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


--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
Go to the top of the page
 
+Quote Post
vlad_new
сообщение Nov 17 2013, 02:01
Сообщение #5


Местный
***

Группа: Участник
Сообщений: 218
Регистрация: 24-06-10
Пользователь №: 58 127



А я не знал что незяяяяя. Взял и включил сопр. В итоге на флоатах скорость поднялась в 12-15 раз, а на дублях в 3-4. sm.gif
Go to the top of the page
 
+Quote Post
AlexeyT
сообщение Nov 17 2013, 07:14
Сообщение #6


Участник
*

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



Цитата(vlad_new @ Nov 17 2013, 06:01) *
А я не знал что незяяяяя. Взял и включил сопр. В итоге на флоатах скорость поднялась в 12-15 раз, а на дублях в 3-4. sm.gif



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

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

в двух вариантах - при включенном и выключенном сопроцессоре.
Меня вот никак не отпускает ощущение, что ДОЛЖНО float ядро хоть как-то ускорять операции double.
Go to the top of the page
 
+Quote Post
vlad_new
сообщение Nov 17 2013, 14:48
Сообщение #7


Местный
***

Группа: Участник
Сообщений: 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 раза. Так что народ прав. В чистом виде для дубля сопр бесполезен. Но при грамотном смешевании дубля и флоута эффект будет.

Go to the top of the page
 
+Quote Post
SII
сообщение Nov 18 2013, 06:37
Сообщение #8


Знающий
****

Группа: Свой
Сообщений: 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
Go to the top of the page
 
+Quote Post
etoja
сообщение Nov 18 2013, 12:19
Сообщение #9


Профессионал
*****

Группа: Свой
Сообщений: 1 121
Регистрация: 14-01-05
Из: Москва
Пользователь №: 1 952



Цитата(AlexeyT @ Nov 16 2013, 15:18) *
Ожидаем поставку процессора с ядром Cortex-M4F с аппаратно реализованными операциями с плавающей точкой (32-битные float).


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

Вы в своём алгоритме скобки правильно расставьте и иногда масштабирование делайте. Так работают алгоритмы цифровой обработки сигналов .
Возможно компилятор gcc часть этой работы сделает и сам при включенной оптимизации.
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Nov 18 2013, 17:33
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



число дабл - это мантисса + порядок.
если его разложить на 2 числа

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

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

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

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

Go to the top of the page
 
+Quote Post
AlexeyT
сообщение Nov 18 2013, 19:37
Сообщение #11


Участник
*

Группа: Участник
Сообщений: 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
Go to the top of the page
 
+Quote Post
jcxz
сообщение Nov 19 2013, 06:53
Сообщение #12


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(Golikov A. @ Nov 18 2013, 23:33) *
я в чем то не прав?

В математике.
То что Вы сказали, переведите на математический язык (формулами).
И поймёте почему.
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Nov 19 2013, 08:32
Сообщение #13


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



ну вот так как-то
(А+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 - половинного порядка, и выравнивание порядков и суммирование

я не утверждаю что все действия при перемножении даблов раскладываются в действия с флотами, мне просто кажется что часть действий при перемножении даблов может быть ускорена при наличии флоат умножителя. Правда не знаю будет ли выигрыш от работы с флотами или легче сразу все сводить к перемножению целых...
Go to the top of the page
 
+Quote Post
jcxz
сообщение Nov 19 2013, 08:50
Сообщение #14


Гуру
******

Группа: Свой
Сообщений: 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-эмуляцией.
Go to the top of the page
 
+Quote Post
SII
сообщение Nov 19 2013, 10:18
Сообщение #15


Знающий
****

Группа: Свой
Сообщений: 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
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Nov 19 2013, 10:25
Сообщение #16


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



я не ошибся, я имел ввиду другое

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

Хотя ваша правда, легче уже сразу переходить к перемножению мантис в целочисленной арифметике, чем мутить такое.
Go to the top of the page
 
+Quote Post
DASM
сообщение Nov 19 2013, 10:43
Сообщение #17


Гуру
******

Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493



Цитата(SII @ Nov 19 2013, 14:18) *
если для перемножения мантисс чисел одинарной точности достаточно лишь одной инструкции 32-разрядного целочисленного умножения, которая у ARMов есть, то для перемножения мантисс чисел двойной точности подходящей инструкции уже нет

ARM разные бывают, стоит уточнить. У ARMv6 хардворный дабл есть.
Go to the top of the page
 
+Quote Post
SII
сообщение Nov 19 2013, 13:55
Сообщение #18


Знающий
****

Группа: Свой
Сообщений: 549
Регистрация: 13-07-10
Из: Солнечногорск-7
Пользователь №: 58 414



Цитата(DASM @ Nov 19 2013, 14:43) *
ARM разные бывают, стоит уточнить. У ARMv6 хардворный дабл есть.


Кажется, мы говорим о разных вещах: Вы о наличии ППЗ, обрабатывающего не только 32-разрядные, но и 64-разрядные вещественные числа, а я -- о программной реализации вещественной арифметики с помощью команд обработки целых чисел, т.е. без ППЗ. Для того, чтобы выполнить умножение мантисс вещественных чисел двойной точности, требуется команда умножения, операндами которой являются 64-разрядные числа. Реально мантисса, конечно, меньше -- если память не изменяет, 52 бита -- но в любом случае 32-разрядное умножение здесь не годится, а команд, умножающих более крупные целые числа, ни у каких ARMов нет.
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Nov 19 2013, 16:28
Сообщение #19


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



а я о теоретической применимости 32 битного флотовского умножителя для ускорения 64 битной дабловской арифметики...%)
Go to the top of the page
 
+Quote Post
SII
сообщение Nov 20 2013, 05:35
Сообщение #20


Знающий
****

Группа: Свой
Сообщений: 549
Регистрация: 13-07-10
Из: Солнечногорск-7
Пользователь №: 58 414



В третий раз повторяю: изучите матчасть, а заодно и математику. Никакого "флотовского умножителя" в природе не существует. Для выполнения операций с вещественными числами используются схемы сложения, умножения, деления и сдвига целых чисел, не имеющие никаких принципиальных отличий от аналогичных узлов, предназначенных для выполнения целочисленной арифметики. Более того, разрядность у вычислительных блоков ППЗ, поддерживающего лишь вещественную арифметику одинарной точности, меньше, чем у аналогичных блоков основного процессора. Например, обычный целочисленный умножитель в основном процессоре позволяет умножить два 32-разрядных целых числа с получением 64-разрядного результата, а пресловутый умножитель в ППЗ, который никакой не "флотовый", а опять-таки самый что ни на есть обычный целочисленный -- лишь два 24-разрядных целых числа (поскольку мантисса вещественных чисел одинарной точности содержит 24 бита). То же самое относится и к другим схемам.

Может быть, теоретически удалось бы извернуться и использовать ППЗ одинарной точности для обработки чисел двойной точности, вот только реализация всего этого будет принципиально такой же, как на целочисленном процессоре без всякого ППЗ, только намного более муторной. Например, для умножения кусков мантисс вещественных чисел двойной точности (размер 53 бита) в любом случае придётся мантиссы разбивать на части и выполнять умножение по кусочкам, а потом складывать промежуточные результаты. На 32-разрядном умножителе основного процессора потребуется 4 операции умножения (32*32 бита с 64-разрядным результатом), а на 24-разрядном умножителе ППЗ -- целых 25 (12*12 бит с 24-разрядным результатом), т.е. даже по одному умножению ППЗ будет проигрывать основному процессору более чем в шесть раз. А ведь требуются ещё сдвиги и сложения, которые на ППЗ реализовать тоже сложней, чем на основном процессоре (если вообще удастся такое сделать -- тут надо думать). Так что такая реализация арифметики двойной точности на ППЗ одинарной точности будет во много медленней, чем её реализация на основном процессоре -- и, что весьма интересно, при этом никакие "плавающие" возможности ППЗ реально использовать невозможно, они лишь мешают.
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Nov 20 2013, 07:05
Сообщение #21


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



ну вот теперь понятно...

а 32 битный умножитель целых, дает 64 бита?

int32_t A;
int32_t B;
int64_t Result;

всегда писал Result = (int64_t)A * (int64_t)B, и тем самым заставлял проц делать сразу все в 64 битах и за несколько тактов. То есть мне стоило писать Result = A * B? или такую хитрость только явным ассемблером получить можно?



Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Nov 20 2013, 08:21
Сообщение #22


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (Golikov A. @ Nov 20 2013, 10:05) *
всегда писал Result = (int64_t)A * (int64_t)B, и тем самым заставлял проц делать сразу все в 64 битах и за несколько тактов. То есть мне стоило писать Result = A * B?
Вы и ваш компилятор делали так, как и надо делать согласно стандарта языка. Если включить оптимизатор, то хороший компилятор должен выкинуть лишние операции и оставить лишь [32]*[32]=[64]


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
SII
сообщение Nov 20 2013, 08:54
Сообщение #23


Знающий
****

Группа: Свой
Сообщений: 549
Регистрация: 13-07-10
Из: Солнечногорск-7
Пользователь №: 58 414



Цитата(Golikov A. @ Nov 20 2013, 11:05) *
а 32 битный умножитель целых, дает 64 бита?


Физически -- да, умножение 32-разрядных чисел даст 64-разрядный результат. Однако удастся ли "в лоб" использовать это на языке высокого уровня (на Си, в частности), я не знаю. На ассемблере ручками -- всегда пожалуйста sm.gif
Go to the top of the page
 
+Quote Post
Golikov A.
сообщение Nov 20 2013, 11:40
Сообщение #24


Гуру
******

Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454



в лоб без оптимизации
[32]*[32]
дает [32]....
имеется ввиду
Result = A * B,
а Result = (int64_t)A * (int64_t)B,
без оптимизации дает больше команд чем просто 32 на 32 умножение, а с оптимизацией я чет не допер посмотреть...
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Nov 20 2013, 12:54
Сообщение #25


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (Golikov A. @ Nov 20 2013, 14:40) *
без оптимизации дает больше команд чем просто 32 на 32 умножение, а с оптимизацией я чет не допер посмотреть...
Без оптимизации получаете ровно то, что просите. Без оптимизации, как и просите.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 22nd July 2025 - 05:31
Рейтинг@Mail.ru


Страница сгенерированна за 0.01617 секунд с 7
ELECTRONIX ©2004-2016