|
asm на AVR, оптимальные конструкции |
|
|
|
Jan 28 2012, 15:48
|
Местный
  
Группа: Свой
Сообщений: 352
Регистрация: 13-08-11
Из: Воронеж
Пользователь №: 66 710

|
Пишу третий в жизни проект, на AVR, на asm. До того было 2 успешных - на asm и на C. Писать надо именно на asm - по разным причинам. Я понимаю что можно написать на С и посмотреть что там сделает компилятор с оптимизатором, но пока хочется поковыряться самому  Общую логику и алгоритм работы уже составил, осталось красиво реализовать это на asm - оптимально не по размеру кода а по скорости при любых ветках ветвлений - то есть, если кусок кода будет делаться 50 тактов в 99 случаях и 1000 тактов в 1, то пусть лучше он каждый раз делается гарантированно по 500 тактов  Возникают в изобилии коротенькие логически законченные куски для перевода в asm. Например Код signed long int S = 0; float s = 0, ds = 0; signed char P = 0; ...... s = s + ds; if (s < 0) { s = 1 - s; S = S - 1; P = P - 1; if (P < 0) {P = 3} } elseif (s >= 1) { s = s - 1; S = S + 1; P = P + 1; if (P > 3) {P = 0} } В asm s и ds будут в формате с плавающей запятой. Думаю что буду использовать sbrc/sbrs их старшего бита - знака мантиссы. Позже напишу код который придумаю - покритикуете помидорами. А вот насчет Код P = P - 1; if (P < 0) {P = 3} .......... P = P + 1; if (P > 3) {P = 0} } придумал - я просто делаю inc/dec rP а потом мне надо найти красивую команду чтобы просто занулить его старшие 6 разрядов - пока точно не знаю какую - and или lsl rP, 6 + lsr rP, 6 Или еще пример Код float s, ds; unsigned char m; ...... if (ds < 1/128) m = 128 elseif (ds < 1/64) m = 64 elseif (ds < 1/32) m = 32 elseif (ds < 1/16) m = 16 elseif (ds < 1/8) m = 8 elseif (ds < 1/4) m = 4 elseif (ds < 1/2) m = 2 else m = 1 Написано коряво, только суть. Теперь буду думать как это красиво на asm написать... Если есть что сказать - почитаю  За возможные синтаксические ошибки не пинайте - думаю, смысл понятен и так.
Сообщение отредактировал _Ivana - Jan 28 2012, 15:54
|
|
|
|
3 страниц
1 2 3 >
|
 |
Ответов
(1 - 14)
|
Jan 28 2012, 21:13
|
Местный
  
Группа: Свой
Сообщений: 352
Регистрация: 13-08-11
Из: Воронеж
Пользователь №: 66 710

|
Продолжая сумбурные имхоизлияния: Действительно, Код P = P - 1; if (P < 0) {P = 3} .......... P = P + 1; if (P > 3) {P = 0} отлично работает как Код ;dec R22; inc R22; andi R22, (1<<1) + (1<<0) что и следовало ожидать. А вот с плавающей запятой действительно ушел в заплыв  Впервые окунулся в это, и к сожалению обнаружил, что я не могу умножить число в этом формате на 128 просто добавив порядок не меняя мантиссы... Думал что делаю что-то не так, но умножил через библиотеку - действительно меняется мантисса! Видимо, приводится к новому нормализованному представлению, хотя теоретически я пока не понимаю этого до конца - по всем представлениям должен скакать только порядок. Значит придется умножать через библиотеку, будет больше тактов и не обязательно тогда на степень 2-ки...
|
|
|
|
|
Jan 29 2012, 09:41
|
Местный
  
Группа: Свой
Сообщений: 352
Регистрация: 13-08-11
Из: Воронеж
Пользователь №: 66 710

|
Пообщался с умными людьми, они мне вправили мозги насчет стандарта IEEE - что там 23 бита мантиссы  и младший бит порядка лежит в старшем байте мантиссы. А я как наивный читал комментарии к библиотеке и верил им, не взирая даже на орфографические ошибки Код ;******************************************************************************* ************* ;* Полная компактная и скоростная библиотека арифметических процедур для работы с числом ;* в 32-х разрядном формате стандарта IEEE с плавающей точкой. ;* Автор: 1998,1999 by Jack Tidwell. ;* Исправление ошибок и переработка с целью уменьшения размера кода: Зубовым Сергеем, 2008 г. ;* Размер кода: 208 words (410 bytes) ;* Число с плавающей точкой хранится в четырёх байтах: ;* 1-й - байт порядка (expon1, expon2) ;* cостоит из бит: 7 - знак числа (1 - отрицательное число) ;* 6 - знак порядка (1 - положительный порядок) ;* NEG( 0x40 - 0x0[0..5] ) - значение порядка ;* 2-й - старший байт мантиссы (mant1h, mant2h) ;* 3-й - средний байт мантиссы (mant1m, mant2m) ;* 4-й - младший байт мантиссы (mant1, mant2) ;* Процедуры: ;* FADD - сложение ;* FSUB - вычетание ;* F_MUL - умножение ;* FDIV - длеление ;* FLTNEG - инвертирование знака первого аргумента ;* MINRES - обнуление первого аргумента ;* SWAPACC - обмен содержимым между первым и вторым аргументами ;* ITOF - преобразование формата числа из целого знакового в формат с плвающей точкой ;* FTOI - преобразование формата числа из формата с плвающей точкой в целый знаковый ;******************************************************************************* ************** Сейчас попробую и думаю все получится. И допишу в библиотеку функцию умножения на степень 2. А может и ещё какие.
|
|
|
|
|
Jan 29 2012, 11:49
|

Гуру
     
Группа: Свой
Сообщений: 2 076
Регистрация: 10-09-08
Пользователь №: 40 106

|
Не буду утверждать на 100% что это правильно, но у меня както исторически сложилось хранить в 1-м байте младший а в 4-м старший байт целого 32-х битного числа. С float не работал. Неплохо бы добавить ешё и фукцию преобразования числа в строку ASCII. Цитата(_Pasha @ Jan 29 2012, 14:31)  Ы! avr-libcБерем , курим папочку /libm/fplib/ и, (оно ж уже работает) выбрасываем все ненужные (с субъективной точки зрения) вещи. Я думаю это будет тошонада. Нифига не понял как и что там искать?
|
|
|
|
|
Jan 29 2012, 12:02
|
Местный
  
Группа: Свой
Сообщений: 352
Регистрация: 13-08-11
Из: Воронеж
Пользователь №: 66 710

|
_Pasha спасибо, покурю. Но одно из требований заказчика - использовать именно данную Tidwell - Зубова библиотеку для плавучки. Уже почти разобрался, дописал функцию. zombi вы таким образом сами себе организуете литл-биг эндиан как вам удобно. В этом прелесть чистого asm - все организуешь сам. И в этом же его неудобство, смотря с какой стороны посмотреть  А если есть сторонняя библиотека - проще подстроиться под её формат. А если их не одна - то позаботиться о совпадении или приведении форматов. ЗЫ помимо плавучки продолжаю думать над остальными банальными человеческими вещами - как переводить их на РИСК язык команд asm...
|
|
|
|
|
Jan 30 2012, 01:14
|

I WANT TO BELIEVE
     
Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751

|
Если честно, то я не понимаю зачем плавучка на AVR и уж тем более(мне кажется) не стоит ради неё так напрягаться, чтобы аж согласовывать форматы на асме и т.д.. ИМХО, потратить те-же силы на перевод расчётов на фиксированную точку будет разумнее и по тактам и в плане опыта работы с фиксированной точкой, который будет применим на любых архитектурах, в отличие от АВР асма. Может быть ещё раз переговорить с заказчиком по поводу той плавучей библиотеки и её необходимости?
P.S. Использовать плавучку удобно там, где есть FPU или там где есть для неё запас производительности(без FPU) а расчёты нет сил/желания/времени переводить в фиксированную точку. В остальных случаях от плавучки толку ноль, ибо как не крути, а она просто пожирает ресурсы. Мне кажется, что при условии отсутствия FPU, один и тот-же алгоритм в фиксированной точке всегда обгонит плавучую реализацию(хоть как бы вы ту плавучку не оптимизировали). Если не прав - старшие товарищи пусть поправят.
Для вселения уверенности ещё добавлю, что в фиксированную точку переводят даже такие сложные вещи как всевозможные кодеки, где вообще сплошная математика, неподъёмная для AVR. Более того, есть и такие шедевры, где к примеру вообще не используется деление. Т.е. в масштабах AVR перевод алгоритма в фиксированную точку видится мне не такой уж сложной и трудоёмкой задачей.
--------------------
The truth is out there...
|
|
|
|
|
Jan 30 2012, 04:23
|
Гуру
     
Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322

|
Цитата(sigmaN @ Jan 30 2012, 03:14)  Если честно, то я не понимаю зачем плавучка на AVR Чтобы считать с использование float, math... что тут непонятного Цитата(sigmaN @ Jan 30 2012, 03:14)  не стоит ради неё так напрягаться, чтобы аж согласовывать форматы на асме и т.д.. Да, не стоит Цитата(sigmaN @ Jan 30 2012, 03:14)  Мне кажется, что при условии отсутствия FPU, один и тот-же алгоритм в фиксированной точке всегда обгонит плавучую реализацию(хоть как бы вы ту плавучку не оптимизировали). Конечно обгонит. И где те алгоритмы? Цитата(sigmaN @ Jan 30 2012, 03:14)  того, есть и такие шедевры, где к примеру вообще не используется деление. Во дают Цитата(sigmaN @ Jan 30 2012, 03:14)  Т.е. в масштабах AVR перевод алгоритма в фиксированную точку видится мне не такой уж сложной и трудоёмкой задачей. Где можно скачать?
|
|
|
|
|
Jan 30 2012, 05:53
|
Местный
  
Группа: Участник
Сообщений: 313
Регистрация: 2-07-11
Пользователь №: 66 023

|
Цитата(sigmaN @ Jan 30 2012, 04:14)  Мне кажется, что при условии отсутствия FPU, один и тот-же алгоритм в фиксированной точке всегда обгонит плавучую реализацию(хоть как бы вы ту плавучку не оптимизировали). Если не прав - старшие товарищи пусть поправят.
Для вселения уверенности ещё добавлю, что в фиксированную точку переводят даже такие сложные вещи как всевозможные кодеки, где вообще сплошная математика, неподъёмная для AVR. Более того, есть и такие шедевры, где к примеру вообще не используется деление. Т.е. в масштабах AVR перевод алгоритма в фиксированную точку видится мне не такой уж сложной и трудоёмкой задачей. Есть алгоритмы, где диапазон значений возникающих чисел очень велик. Кодек JPEG в этом смысле удобен - там на всех этапах числа в вполне определённых нешироких пределах. Про другие кодеки точно не знаю но вероятно тоже. А вот попробуйте найти собственные значения матрицы 10х10. Пусть даже все её элементы - целые от -127 до 127. Для AVR задача вполне по потребностям в памяти. То есть алгоритм в фиксированной точке всегда обгонит плавучую реализацию, но только если этот алгоритм в фиксированной точке вообще получается.
|
|
|
|
|
Jan 30 2012, 15:48
|
Местный
  
Группа: Свой
Сообщений: 352
Регистрация: 13-08-11
Из: Воронеж
Пользователь №: 66 710

|
Спасибо всем отписавшимся, а sigmaN - отдельное  Судя по всему, как я ни ужимаюсь, как ни дописываю дополнительные функции в и так уже "скоростную" плавучую библиотеку - я не влезаю по скорости. Причем, в разы и десятки раз  Собственно задача - драйвер железяки, требуется высокоскоростное управление по 2-м каналам ШИМ, выдача кучи дополнительной информации и реакция на входящие параметры, которые будут передаваться как раз в этой плавучке. Плюс это обязательно на ATmega48P с 512 байт ОЗУ и без аппаратной плавучки - ибо их судя по всему у заказчика на складе завались и надо куда-то применить  Так что всякие Кортексы, AT32UC3C и прочее с аппаратной плавучкой и щедрыми мегагерцами будут мной осваиваться в других проектах  Хотел вынести расчеты в отдельные периодические "паузы задумчивости" - нельзя, нужна реалтаймовая реакция на датчики обратных связей. Поэтому идея с фиксированной точкой выглядит возможным выходом, тем более что я и так вынужден хранить в плавучке только дробные части чисел а целые - в отдельных байтах, чтобы не терять абсолютную точность! Так что сегодня пойду обсуждать с руководителем проекта перевод плавучей входящей/исходящей информации в фиксированную точку и внутренние расчеты уже в ней. Далеко не факт что и при этом уложусь, но все интереснее попробовать варианты ЗЫ я этот проект вообще воспринимаю как тренировочный чтобы руку набить и опыт получить. В плавучке поплавал, теперь в фиксах попробую - это даже хорошо.
Сообщение отредактировал _Ivana - Jan 30 2012, 15:49
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|