Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Отключение плавучки и KGP
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Cредства разработки для МК > GNU/OpenSource средства разработки
Ash_snz
Господа. имеется тема для размышления.
Есть процессор мипсовый с сопроцессором для плавучки. 32-х разрядные вычисления делаются на отлично.
Цель попробовать отказаться от 32-х разрядов и все плавучие вычисления реализовать на 16 разрядах, соответственно не используя дополнительное ядро.

Я так понимаю один из вариантов -использование фиксированной запятой. Сам я с этим не сталкивался, кто знаком подскажите где можно изучить вопрос?

Второй вариант - перекинуть это на сильные плечи компилятора. Пробовал с помощью KGP и библиотек сбилденных на soft-float реализовать ту же программу. Компилятор ругается на многие андефайны, относящиеся к плавучке, хотя в libm их видно. Как итог - не собирается.

Кто, что может подсказать по этому вопросу?
alx2
Цитата(Ash_snz @ Nov 5 2012, 19:39) *
Компилятор ругается на многие андефайны, относящиеся к плавучке, хотя в libm их видно.

Кто, что может подсказать по этому вопросу?

Если Вы уточните, на какие именно "андефайны" ругается компилятор, нам, вероятно, будет легче что-либо подсказать.
Пока могу лишь предположить, что Вы забыли #include <math.h>...
Ash_snz
Цитата(alx2 @ Nov 8 2012, 09:17) *
Если Вы уточните, на какие именно "андефайны" ругается компилятор, нам, вероятно, будет легче что-либо подсказать.
Пока могу лишь предположить, что Вы забыли #include <math.h>...

Хм. Надо проверить. math.h не должен был никуда отвалиться. Отпишу обязательно.
klen
я думаю решим вопрос, только зачем надевать штаны через голову если есть FPU, сдается что Вы не пытаетесь решить задачу а пытаетесь решить задачу так как Вам хочется.

рас уж поднялась тема про мипсы то можно по ходу и преесобрать все. какое ядро?
Ash_snz
math.h на месте.
вот так ругается:
Код
(.text+OxleO): undefined reference to "_floatsisf'
main.о:  In function 'rs_transmit_digit':
(.text+Oxlf8):  undefined reference to "_floatsisf'
main, о:  In function    'rs_transmit_digit' :
(.text+0x204):  undefined reference to '_mulsf3'
main.о:  In function 'rs_transmit_digit1:
(.text+0x224):  undefined reference to '_fixsfsi'
main, о :  In function    rs_transmit_digit' :
(.text+0x808):  undefined reference to "_subsf31
main.o:  In function 'cycle_2_datchika':
(.text+0xac8):  undefined reference to "_addsf31
main.o:  In function "cycle_2_datchika1:
(.text+0xb2c): undefined reference to "_extendsfdf2'
main.o:  In function ''cycle_2_datchika' :
(.text+0xb58): undefined reference to "_divdf31
main.o:  In function 'cycle_2_datchika1:
(.text+Oxcdc): undefined reference to "_truncdfsf2'
main.o:  In function "cycle_2_datchika1:
( . text+0xce4) : undefined reference to   _truncdf sf 2 1
main.o:  In function vcycle_2_datchika1:
(.text+0xe48):  undefined reference to "_subdf3'
main.o:   In function "cycle_2_datchika1:
(.text+0xe68):  undefined reference to "_truncdfsf21
с:\kgp_mips_elf\mips-kgp-elf\lib\libm.a(lib_a-w_sqrt.o): In function "sqrf: (.text.sgrt+0x54):  undefined reference to -_ltdf21
с:\kgp_mips_elf\mips-kgp-elf\lib\libm.a(lib_a-w_sqrt.o): In function "sqrt": (.text.sqrt+0xa8):  undefined reference to "_divdf3'
c:\kgp_mips_elf\mips-kgp-elf\lib\libm.adib_a-e_sqrt.o):  In function "_ieee754__sqrt' :
(.text._ieee754_sqrt+0x34):  undefined reference to "_muldf3'
с:\kgp_mips_elf\mips-kgp-elf\lib\libm.a(lib_a-e_sqrt.o):  In function _ieee754_sqrt1 :
(.text._ieee754_sqrt+0x48):  undefined reference to "_adddf3'
с:\kgp_mips_elf\mips-kgp-elf\lib\libm.a(lib_a-e_sqrt.o):  In function "_ieee754_sqrt1:
(.text._ieee754_sqrt+0x84): undefined reference to *_subdf3'
с:\kgp_mips_elf\mips-kgp-elf\lib\libm.a(lib_a-e_sqrt.o):  In function "_ieee754_sqrt1:
(.text._ieee754_sqrt+0x98): undefined reference to "_divdf31
cs-make:  ***   [main.elf]   Error 1

Прям и не знаю что делать...

Цитата(klen @ Nov 9 2012, 04:03) *
я думаю решим вопрос, только зачем надевать штаны через голову если есть FPU, сдается что Вы не пытаетесь решить задачу а пытаетесь решить задачу так как Вам хочется.

рас уж поднялась тема про мипсы то можно по ходу и преесобрать все. какое ядро?
Ядро многострадального R3000 (комдив, вестимо sm.gif ). Дело даже не в том - как решить задачу. Это попытка научиться и попробовать работать без плавучки, а также выяснить разницу в производительности.
Вот только не понимаю, что можно пересобрать? у нас есть сборка под наш проц и lib.m как с плавучкой так и без, с плавучкой работает, а вот без - нет.

Чувствую где-то пробел в моих знаниях sm.gif
cant
если там ядро заточено для плавучки, то используйте и не парьтесь.


Занимался когда-то по необходимости (по скорости не пролазил в p30F6014A).

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

вот пример фикс числа для ДСпик:

Код
#define fixed long
fixed pi =        0x3243f;            // 3,14


fixed sin_fixed(fixed x){
    unsigned char a;
    fixed x_to_pi; // = x * pi / 180;
    fixed res = x * pi / 180;

    if ( x >=0 && x<=90 ){
        a = 1;
        x_to_pi = res;
    }
    if ( x >90 && x<=180 ){
        a = 1;
        x_to_pi = -1*(res - pi);
    }
    if ( x >180 && x<=270 ){
        a = -1;
        x_to_pi = res - pi;
    }
    if ( x >270 && x<360 ){
        a = -1;
        x_to_pi = -1*(res - pi<<1);
    }
    
    fixed s = (( x_to_pi * x_to_pi ) >> 15);
    res = (x_to_pi * ((s/6) * ((s/20) - (1<<15)) + (1<<15) )) >> 15;

    if(a>0){
        return   res;
    }
    else{
        return -1 * res;
    }
}



PS сейчас сижу пытаюсь догнать что тогда накидал wacko.gif . И как понять как он работает ??? blink.gif
Ash_snz
Цитата(cant @ Nov 11 2012, 02:15) *
если там ядро заточено для плавучки, то используйте и не парьтесь.
Занимался когда-то по необходимости (по скорости не пролазил в p30F6014A).
Еще нужно после перевода матиматики обязательно сделать расчет на ошибку, т.к. ошибка полюбому выше будет
вот пример фикс числа для ДСпик:
PS сейчас сижу пытаюсь догнать что тогда накидал wacko.gif . И как понять как он работает ??? blink.gif

т.е. мне без вариантов нужно переписать под себя математику? немного печально, но предсказуемо...
alx2
Цитата(Ash_snz @ Nov 10 2012, 21:56) *
math.h на месте.
вот так ругается:
Код
(.text+OxleO): undefined reference to "_floatsisf'
main.о:  In function 'rs_transmit_digit':

Так это у Вас вовсе не компилятор ругается, а линкер!
Следовательно, разбираться надо не с инклудами, а с библиотеками. Судя по именам символов, у Вас не подключена библиотека libgcc.
Ash_snz
Цитата(alx2 @ Nov 12 2012, 10:29) *
Так это у Вас вовсе не компилятор ругается, а линкер!
Следовательно, разбираться надо не с инклудами, а с библиотеками. Судя по именам символов, у Вас не подключена библиотека libgcc.
блин, как догадался? sm.gif пойду проверю.

и почему я так не могу догадаться?! sad.gif
alx2
Цитата(Ash_snz @ Nov 12 2012, 20:37) *
блин, как догадался? sm.gif пойду проверю.

Вы будете смеяться. sm.gif Я тупо погрепал имя символа по своим библиотекам. Сначала тут:
Код
alx% grep -rl _floatsisf /usr/local/arm-elf/lib
/usr/local/arm-elf/lib/thumb/libm.a
/usr/local/arm-elf/lib/libm.a

Но здесь этот символ оказался Undefined:
Код
alx% arm-elf-nm /usr/local/arm-elf/lib/libm.a|grep _floatsisf
         U __floatsisf
         U __floatsisf
         U __floatsisf
         U __floatsisf
         U __floatsisf
         U __floatsisf
         U __floatsisf
         U __floatsisf
         U __floatsisf
         U __floatsisf
         U __floatsisf
         U __floatsisf
         U __floatsisf
         U __floatsisf
         U __floatsisf
         U __floatsisf
         U __floatsisf

А вот тут он нашелся:
Код
alx% grep -rl _floatsisf /usr/local/lib/gcc/arm-elf
/usr/local/lib/gcc/arm-elf/4.5.2/plugin/include/insn-flags.h
/usr/local/lib/gcc/arm-elf/4.5.2/libgcc.a
/usr/local/lib/gcc/arm-elf/4.5.2/thumb/libgcc.a
/usr/local/lib/gcc/arm-elf/4.5.2/fpu/libgcc.a
alx% arm-elf-nm /usr/local/lib/gcc/arm-elf/4.5.2/libgcc.a |grep _floatsisf
000001d0 T __floatsisf
Ash_snz
Цитата(alx2 @ Nov 13 2012, 17:02) *
Вы будете смеяться. sm.gif Я тупо погрепал имя символа по своим библиотекам.

Благодарствую за подсказку! beer.gif
В итоге добавил libgcc и libg и все собралось. Скорость выполнения уменьшилась в 50 раз, точность (на удивление) осталась на том же уровне! /тестим дальше/

Остался последний и главный вопрос.
Существуют ли способы реализации плавучки, а точнее даже дробных вычислений не с 32-мя разрядами, а с 16-ю?
Понимаю, что для перехода придется изменять программу. вопрос в том как? Куда двигаться, кто знает?
может кто реализовывал вычисления на 16-ти разрядных системах без сопроцессоров?
maksimp
Цитата(Ash_snz @ Nov 13 2012, 19:18) *
Скорость выполнения уменьшилась в 50 раз,

Ядро ARM тратит около 50 тактов на сложение или умножение с 32 битной плавающей точкой при отсутствии аппаратной поддержки. То есть у вас аппаратно операции за 1 такт выполняются.
Цитата(Ash_snz @ Nov 13 2012, 19:18) *
точность (на удивление) осталась на том же уровне!

Если реализация аппаратного и программного вычисления соответствуют стандарту, то операциии + - * / дают чётко определённый результат. Поэтому так и должно быть.
Цитата(Ash_snz @ Nov 13 2012, 19:18) *
Существуют ли способы реализации плавучки, а точнее даже дробных вычислений не с 32-мя разрядами, а с 16-ю?

Есть такое. Ищите в сети "half precision floating point".
Есть даже процессоры с аппаратной поддержкой такого.
cant
Цитата(Ash_snz @ Nov 13 2012, 20:18) *
Скорость выполнения уменьшилась в 50 раз, точность (на удивление) осталась на том же уровне! /тестим дальше/


скорее увеличилась biggrin.gif .

С точностью смотрите окуратно: у меня количество знаков после запятой было критично и вначале точность поплыла, увеличивал количество знаков после запятой, чтоб проходить по точности.
Ash_snz
Цитата(maksimp @ Nov 13 2012, 23:14) *
Ядро ARM тратит около 50 тактов на сложение или умножение с 32 битной плавающей точкой при отсутствии аппаратной поддержки. То есть у вас аппаратно операции за 1 такт выполняются.
Наше ядро тратит до 16 тактов на деление, на умножение до 8 кажется тактов.
Цитата(maksimp @ Nov 13 2012, 23:14) *
Если реализация аппаратного и программного вычисления соответствуют стандарту, то операциии + - * / дают чётко определённый результат. Поэтому так и должно быть.

Есть такое. Ищите в сети "half precision floating point".
Есть даже процессоры с аппаратной поддержкой такого.
Спасибо, уже ищу.


Цитата(cant @ Nov 14 2012, 00:06) *
скорее увеличилась biggrin.gif .

С точностью смотрите окуратно: у меня количество знаков после запятой было критично и вначале точность поплыла, увеличивал количество знаков после запятой, чтоб проходить по точности.
Как меняли количество знаков? что за методы?
maksimp
Цитата(Ash_snz @ Nov 14 2012, 20:03) *
Наше ядро тратит до 16 тактов на деление, на умножение до 8 кажется тактов.

Вы наверное про целочисленные операции. Деление вроде до 12 тактов, умножние 1 или 2.
А я имел в виду вычисления с плавающей точкой без аппаратной поддержки. То есть специальная процедура, используя множество целочисленных команд, выделяет знак, мантиссу, порядок, проверяет операнды на INF и NAN, потом всё это обрабатывает и формирут результат. Это гораздо дольше. Деление около 200 тактов.
cant
Цитата(Ash_snz @ Nov 14 2012, 21:03) *
Как меняли количество знаков? что за методы?


В общем ничего особенного: вначале из лонг два байта было на дробь, т.е точность 1/65536. потом добавил пол байта за счет уменьшения целой части - дипозон чисел позволял.

сделал это только там, где критична была погрешность, в остальном коде обычные числа.
Ash_snz
Цитата(maksimp @ Nov 15 2012, 00:14) *
Вы наверное про целочисленные операции. Деление вроде до 12 тактов, умножние 1 или 2.
А я имел в виду вычисления с плавающей точкой без аппаратной поддержки. То есть специальная процедура, используя множество целочисленных команд, выделяет знак, мантиссу, порядок, проверяет операнды на INF и NAN, потом всё это обрабатывает и формирут результат. Это гораздо дольше. Деление около 200 тактов.
Да, я про аппаратную реализацию вычислений сопроцессора.


Цитата(cant @ Nov 15 2012, 01:28) *
В общем ничего особенного: вначале из лонг два байта было на дробь, т.е точность 1/65536. потом добавил пол байта за счет уменьшения целой части - дипозон чисел позволял.

сделал это только там, где критична была погрешность, в остальном коде обычные числа.
Т.е. свой тип переменной определяли и соответственно своя обработка?
maksimp
Цитата(Ash_snz @ Nov 14 2012, 20:03) *
Наше ядро тратит до 16 тактов на деление, на умножение до 8 кажется тактов.

Цитата(Ash_snz @ Nov 15 2012, 19:38) *
Да, я про аппаратную реализацию вычислений сопроцессора.

Тогда странно почему, как вы пишете, скорость выполнения уменьшилась в 50 раз.
Деление программно 200 тактов, аппаратно 16 тактов.
Умножение программно 50 тактов, аппаратно 8 тактов.
Скорость программного выполнения этих операций я замерял.
Ash_snz
Цитата(maksimp @ Nov 16 2012, 01:02) *
Тогда странно почему, как вы пишете, скорость выполнения уменьшилась в 50 раз.
Деление программно 200 тактов, аппаратно 16 тактов.
Умножение программно 50 тактов, аппаратно 8 тактов.
Скорость программного выполнения этих операций я замерял.
Возможно я немного не корректно написал. проверялось на одной из задач. и длительность выполнения именно этой задачи выросла в 50 раз.
Тут дело не в тактах sm.gif
cant
Цитата(Ash_snz @ Nov 15 2012, 19:38) *
Да, я про аппаратную реализацию вычислений сопроцессора.


Т.е. свой тип переменной определяли и соответственно своя обработка?


Да. свой тип, своя обработка.

demiurg_spb
Цитата(cant @ Nov 16 2012, 22:54) *
Да. свой тип, своя обработка.
Нынче немного проще должно быть с этим...
http://gcc.gnu.org/onlinedocs/gcc/Fixed_002dPoint.html
Ash_snz
Цитата(demiurg_spb @ Nov 21 2012, 18:16) *
Нынче немного проще должно быть с этим...
http://gcc.gnu.org/onlinedocs/gcc/Fixed_002dPoint.html
хм, а я нечто другое читал. спасибо.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.