Отговори на тема  [ 23 мнения ]  Отиди на страница 1, 2  Следваща
float const -> double 
Автор Съобщение
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Пон Сеп 27, 2004 9:22 am
Мнения: 15501
Местоположение: София
Мнение float const -> double
Цитат:
int a,b;
a = 0.9 * a + 0.1 * b;


В горния израз компилатора(gcc) не следва ли да ползва double аритметика?

_________________
"Да еба и шибаната държава" мислеше си Гошо, докато се опитваше да улучи кофата за боклук от балкона на осмия етаж.


Пон Яну 11, 2021 5:50 pm
Профил ICQ
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Нед Фев 26, 2006 6:52 pm
Мнения: 11265
Местоположение: Добрич
Мнение Re: float const -> double
Така както си го дал най-вероятно е оптимизирал нещата и се учудвам, че не е останал само на int ;-)

реално имаш int на входа и int на изхода и може да се компилира просто като: (a*9 +b)/10 ;-)


Пон Яну 11, 2021 6:01 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Пон Сеп 27, 2004 9:22 am
Мнения: 15501
Местоположение: София
Мнение Re: float const -> double
Не, оказа се, че има скрит -fsingle-precision-constant в тая версия на чибито, която ползваме. Което е грешка, оправил си го е човека в по-новите.

Ето тук е описано и що е грешка да се ползва тая опция, нарушава правилата на езика и може да доведе до кофти резултати при някой специфични математики:

https://github.com/ArduPilot/ardupilot/issues/5620

_________________
"Да еба и шибаната държава" мислеше си Гошо, докато се опитваше да улучи кофата за боклук от балкона на осмия етаж.


Последна промяна Цецо на Пон Яну 11, 2021 6:18 pm, променена общо 1 път



Пон Яну 11, 2021 6:14 pm
Профил ICQ
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Нед Фев 26, 2006 6:52 pm
Мнения: 11265
Местоположение: Добрич
Мнение Re: float const -> double
не знам, в случая ще е грешка ако компилаторът не го оптимизира ;-)


Пон Яну 11, 2021 6:16 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Пон Сеп 27, 2004 9:22 am
Мнения: 15501
Местоположение: София
Мнение Re: float const -> double
Ми не го оптимизира. Тоест оптимизира нещо, но пак вика библиотеките за double сметки. Ако я няма въпросната опция. Ако я има вика библиотеките за float (или ползва FPU-то ако е налично).

_________________
"Да еба и шибаната държава" мислеше си Гошо, докато се опитваше да улучи кофата за боклук от балкона на осмия етаж.


Пон Яну 11, 2021 6:22 pm
Профил ICQ
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Пон Сеп 27, 2004 9:22 am
Мнения: 15501
Местоположение: София
Мнение Re: float const -> double
pPl->dc_ir и dc_ir са int32_t

gcc е версия 6 нещо си, желязото M4F, компилатора е конфигуриран с -mfloat-abi=hard -mfpu=fpv4-sp-d16

На -О2
Цитат:
pPl->dc_ir = 0.9 * pPl->dc_ir + 0.1 * dc_ir;
801a8d0: f8d4 0090 ldr.w r0, [r4, #144] ; 0x90
801a8d4: f7f5 fe96 bl 8010604 <__aeabi_ui2d>
801a8d8: a37d add r3, pc, #500 ; (adr r3, 801aad0 <pl_process+0x350>)
801a8da: e9d3 2300 ldrd r2, r3, [r3]
801a8de: f7f5 ff07 bl 80106f0 <__aeabi_dmul>
801a8e2: 4680 mov r8, r0
801a8e4: 4650 mov r0, sl
801a8e6: 4689 mov r9, r1
801a8e8: f7f5 fe8c bl 8010604 <__aeabi_ui2d>
801a8ec: a37a add r3, pc, #488 ; (adr r3, 801aad8 <pl_process+0x358>)
801a8ee: e9d3 2300 ldrd r2, r3, [r3]
801a8f2: f7f5 fefd bl 80106f0 <__aeabi_dmul>
801a8f6: 4602 mov r2, r0
801a8f8: 460b mov r3, r1
801a8fa: 4640 mov r0, r8
801a8fc: 4649 mov r1, r9
801a8fe: f7f5 fd45 bl 801038c <__adddf3>
801a902: f7f6 f935 bl 8010b70 <__aeabi_d2uiz>
801a906: 4603 mov r3, r0
801a908: 9003 str r0, [sp, #12]
801a90a: f8c4 3090 str.w r3, [r4, #144] ; 0x90


на -О0

Цитат:
pPl->dc_ir = 0.9 * pPl->dc_ir + 0.1 * dc_ir;
801fca2: 9b0e ldr r3, [sp, #56] ; 0x38
801fca4: f8d3 3090 ldr.w r3, [r3, #144] ; 0x90
801fca8: 4618 mov r0, r3
801fcaa: f7f0 fcab bl 8010604 <__aeabi_ui2d>
801fcae: a372 add r3, pc, #456 ; (adr r3, 801fe78 <pl_analyze+0x288>)
801fcb0: e9d3 2300 ldrd r2, r3, [r3]
801fcb4: f7f0 fd1c bl 80106f0 <__aeabi_dmul>
801fcb8: 4603 mov r3, r0
801fcba: 460c mov r4, r1
801fcbc: 4625 mov r5, r4
801fcbe: 461c mov r4, r3
801fcc0: 980b ldr r0, [sp, #44] ; 0x2c
801fcc2: f7f0 fc9f bl 8010604 <__aeabi_ui2d>
801fcc6: a36e add r3, pc, #440 ; (adr r3, 801fe80 <pl_analyze+0x290>)
801fcc8: e9d3 2300 ldrd r2, r3, [r3]
801fccc: f7f0 fd10 bl 80106f0 <__aeabi_dmul>
801fcd0: 4602 mov r2, r0
801fcd2: 460b mov r3, r1
801fcd4: 4620 mov r0, r4
801fcd6: 4629 mov r1, r5
801fcd8: f7f0 fb58 bl 801038c <__adddf3>
801fcdc: 4603 mov r3, r0
801fcde: 460c mov r4, r1
801fce0: 4618 mov r0, r3
801fce2: 4621 mov r1, r4
801fce4: f7f0 ffe4 bl 8010cb0 <__aeabi_d2uiz>
801fce8: 4602 mov r2, r0
801fcea: 9b0e ldr r3, [sp, #56] ; 0x38
801fcec: f8c3 2090 str.w r2, [r3, #144] ; 0x90


На -О0 -fsingle-precision-constant

Цитат:
pPl->dc_ir = 0.9 * pPl->dc_ir + 0.1 * dc_ir;
801fbd2: 9b0e ldr r3, [sp, #56] ; 0x38
801fbd4: f8d3 3090 ldr.w r3, [r3, #144] ; 0x90
801fbd8: ee07 3a90 vmov s15, r3
801fbdc: eef8 7a67 vcvt.f32.u32 s15, s15
801fbe0: ed9f 7a6b vldr s14, [pc, #428] ; 801fd90 <pl_analyze+0x270>
801fbe4: ee27 7a87 vmul.f32 s14, s15, s14
801fbe8: 9b0b ldr r3, [sp, #44] ; 0x2c
801fbea: ee07 3a90 vmov s15, r3
801fbee: eef8 7a67 vcvt.f32.u32 s15, s15
801fbf2: eddf 6a68 vldr s13, [pc, #416] ; 801fd94 <pl_analyze+0x274>
801fbf6: ee67 7aa6 vmul.f32 s15, s15, s13
801fbfa: ee77 7a27 vadd.f32 s15, s14, s15
801fbfe: eefc 7ae7 vcvt.u32.f32 s15, s15
801fc02: ee17 2a90 vmov r2, s15
801fc06: 9b0e ldr r3, [sp, #56] ; 0x38
801fc08: f8c3 2090 str.w r2, [r3, #144] ; 0x90

_________________
"Да еба и шибаната държава" мислеше си Гошо, докато се опитваше да улучи кофата за боклук от балкона на осмия етаж.


Пон Яну 11, 2021 6:26 pm
Профил ICQ
Online
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Вто Дек 14, 2004 1:31 pm
Мнения: 3849
Мнение Re: float const -> double
А онзи се оплаквахте, че на питона версиите му били досадни.... :D


Пон Яну 11, 2021 7:20 pm
Профил WWW
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Пон Сеп 27, 2004 9:22 am
Мнения: 15501
Местоположение: София
Мнение Re: float const -> double
Е не, тука проблема се оказа в междинния слой. Компилатора се държи адекватно, правилата са стриктни и си ги спазва.

_________________
"Да еба и шибаната държава" мислеше си Гошо, докато се опитваше да улучи кофата за боклук от балкона на осмия етаж.


Пон Яну 11, 2021 7:25 pm
Профил ICQ
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Вто Окт 11, 2011 11:53 pm
Мнения: 4582
Местоположение: Brussels / Пловдив
Мнение Re: float const -> double
miro_atc написа:
не знам, в случая ще е грешка ако компилаторът не го оптимизира ;-)

Проблемът е, че 0.1 и 0.9 нямат точно представяне с floating point числа (без значение дали е float или double) и съответно при някои числа ще има разлика с оптимизираният код (ако например го оптимизра до (a*9 +b)/10)

Tакива оптимизации са работа на задклавиатурното устройство, работата на компилатора е стриктно да следва каквото му е подадено като сорс и да оптимизира само там където няма да има странични ефекти.

Аз бих го "оптимизирал" и като (a*7+b)>>3 за да избягам от делението, но само ако това не се отразява на съответния алгоритъм.

_________________
Мразя да мразя ...


Пон Яну 11, 2021 7:48 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Пон Сеп 27, 2004 9:22 am
Мнения: 15501
Местоположение: София
Мнение Re: float const -> double
Абе за оптимизациите е ясно. Въпроса беше - дробна константа, без спецификатор не се ли приема за double? И ако да, що при мен не се случваше. Намери се обяснението.

_________________
"Да еба и шибаната държава" мислеше си Гошо, докато се опитваше да улучи кофата за боклук от балкона на осмия етаж.


Пон Яну 11, 2021 8:57 pm
Профил ICQ
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Нед Сеп 26, 2004 4:11 pm
Мнения: 3750
Местоположение: София
Мнение Re: float const -> double
miro_atc написа:
....

реално имаш int на входа и int на изхода и може да се компилира просто като: (a*9 +b)/10 ;-)


Понеже съм запознат с проблема, да си кажа и аз. Добре, че компилаторът не го е оптимизирал, защото резултатът щеше да е грешен. а*9 щеше да препълни размера на типа ( 32 битов без знак е ) и катеричките нямаше да са това, което изглеждат.


Вто Яну 12, 2021 12:26 am
Профил ICQ
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Нед Фев 26, 2006 6:52 pm
Мнения: 11265
Местоположение: Добрич
Мнение Re: float const -> double
bateAz написа:
Добре, че компилаторът не го е оптимизирал, защото резултатът щеше да е грешен.


Е те затова падат ракетите ;-)

Те това би трябвало да не препълва:
(a*9LL +b)/10LL

За по-оптимална компилация може и така:

Код:
long long ll;

ll = a;
ll += ll << 3;
ll += b;
return ll / 10;


Вто Яну 12, 2021 10:50 am
Профил
Ранг: Форумен бог
Ранг: Форумен бог
Аватар

Регистриран на: Нед Сеп 26, 2004 4:11 pm
Мнения: 3750
Местоположение: София
Мнение Re: float const -> double
miro_atc написа:
...
Те това би трябвало да не препълва:
(a*9LL +b)/10LL

...


Това е ясно. За предишното говорехме.


Вто Яну 12, 2021 10:58 am
Профил ICQ
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Вто Окт 11, 2011 11:53 pm
Мнения: 4582
Местоположение: Brussels / Пловдив
Мнение Re: float const -> double
miro_atc написа:
За по-оптимална компилация може и така:

Код:
long long ll;

ll = a;
ll += ll << 3;
ll += b;
return ll / 10;

Що зорлен го мъчиш компилатора да се чуди какво си имал в предвид. И кода ти става по труден за четене. Такава оптимизация е платформо зависима, т.е. на процесори които имат хардуерно умножение (т.е. почти всички модерно 16, 32, 64 битово) ще е по бързо да се изпълни една инструкция за умножение отколкото две (преместване и събиране). Модерните компилатори ще се оправят достатъчно добре с оптимизиране на такива сметки там където може и има смисъл. Като бонус ако смениш процесора с друг компилатора ще оптимизира за него, докато ако направиш такава оптимизация му вързваш ръцете винаги да ползва преместване и събиране.

_________________
Мразя да мразя ...


Вто Яну 12, 2021 12:31 pm
Профил
Ранг: Форумен бог
Ранг: Форумен бог

Регистриран на: Нед Фев 26, 2006 6:52 pm
Мнения: 11265
Местоположение: Добрич
Мнение Re: float const -> double
palavrov написа:
Такава оптимизация е платформо зависима


Така е... Някой ден подобни оптимизации излизат през носа, играл съм го и тоя филм.
От друга страна, ако човек работи на определена платформа... както да речем аз последните 20г. може да се каже, че сме вече почти женени ;-)
Та в такива случаи, когато по никакъв начин не се очаква генерална смяна си позволявам да се съобразя с конкретната платформа. И само с нея ;-)
В случая хардуерно умножение има, но е 32 битово. И което е още по-зле за 64-бит аритметика се разчита на стандартните библиотеки, демек вика се функция с всичките произтичащи негативи от това. Аз даже се учудвам, че по-горе има float аритметики директно без викане на __eabi_.... Или newlib са го пипнали (не знам аз не го ползвам и следя). Но при всички случаи 64-бит шифтване е по-бързо и позволява съчетание със събирането. То и при умножението има multiply and accumulate, обаче ще стане още по-грозно като код.
А другия проблем специално при GCC че не е много гъвкав с типовете. Разчита ти да му ги укажеш, а аз обикновено избягвам в сорса да има двуумене какъв тип трябва да се ползва. Говоря за изрази където трябва да се прецени дали какъв тип са аргументите и какъв тип резултата и т.н. Примерно в случая делението може да е 64 бит /32 бит, което е значително по-бързо от 64/64. Но не съм сигурен в израз дали GCC няма да му хрумне нещо друго, затова - на парче ;-)


Вто Яну 12, 2021 1:25 pm
Профил
Покажи мненията от миналия:  Сортирай по  
Отговори на тема   [ 23 мнения ]  Отиди на страница 1, 2  Следваща

Кой е на линия

Потребители разглеждащи този форум: 0 регистрирани и 12 госта


Вие не можете да пускате нови теми
Вие не можете да отговаряте на теми
Вие не можете да променяте собственото си мнение
Вие не можете да изтривате собствените си мнения
Вие не можете да прикачвате файл

Търсене:
Иди на:  
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by ST Software for PTF.
Хостинг и Домейни