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

 
 
10 страниц V  « < 4 5 6 7 8 > »   
Reply to this topicStart new topic
> Перенос кода из под ИАРа на WinAVR, возникают некоторые вопросы...
Rst7
сообщение Nov 29 2008, 12:53
Сообщение #76


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

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



Цитата
Во-вторых, я подозреваю, что вероятность выхода результата неких вычислений за границы диапазона (-128...127) намного выше чем диапазона (-32768...32767).


Да ну? Рассмотрим операцию сложения. Независимо от размера - char или int - половина возможных операндов (немного меньше, без 2n, где n - количество разрядов) приведет к переполнению. А значит - вероятность почти 50% и не зависит от размерности smile.gif


--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Nov 29 2008, 19:31
Сообщение #77


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(Rst7 @ Nov 29 2008, 17:53) *
А значит - вероятность почти 50% и не зависит от размерности smile.gif

Но ведь 50% от 0xFFFF - это гораздо больше, чем 50% от 0xFF! smile.gif


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
sonycman
сообщение Nov 29 2008, 21:02
Сообщение #78


Любитель
*****

Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695



Цитата(alx2 @ Nov 29 2008, 15:51) *
Поэтому кодеру очень часто пришлось бы писать явное приведение к типу int, например писать (0 + a + cool.gif / 2 вместо (a + cool.gif / 2. Лично мне это бы не понравилось, т.к. во-первых, больше текста - больше вероятность ошибиться, а во-вторых, ухудшается читаемость кода.

Зачем часто писать явное приведение к int? Разумнее сразу иметь хотя-бы одну переменную размерности int, если обработка данных типа char приводит к образованию переполнения smile.gif
В моём случае (применительно к моему проекту) ситуация совсем обратная. Мне частенько приходится делать явное приведение к char sad.gif
Почему? Потому что я резонно предполагал более эффективную работу восьмибитного ядра именно с "родным" типом данных - с char. Поэтому старался иметь максимальное количество переменных такого типа.

Цитата
Не эквивалентны. В первом случае преобразование к типу char производится перед делением, во втором - после. Например при LCD_WIDTH=96, x=32 и lcdGetStringWidth(text)=0 результат этих выражений будет разным.

Ты говоришь про общий случай. Я - про строку кода конкретной функции lcdPrintText, в которой делимое всегда лежит в пределах 0 <= d < 96.
Поэтому эти выражения совершенно эквивалентны.
Ты можешь возразить - а откуда это может знать компилятор? Я соглашусь - не может он этого знать, он просто "железяка", которой внушили, что она много знает, и которой время от времени приходится "выпрямлять руки". biggrin.gif

Но продолжим о "выражениях".
Благодаря стандарту, первое выражение имеет в два с половиной раза больший объём кода.
А если в программе таких выражений десятки? Тогда мы получаем в коде сотни байт ненужного мусора, что для маленьких кристаллов является актуальной проблемой.

Что мы делаем? Мы делаем явное приведение типов/разбиваем выражения на несколько частей и т.д. и т.п., что, как ты верно заметил,
Цитата
лично мне это бы не понравилось, т.к. во-первых, больше текста - больше вероятность ошибиться, а во-вторых, ухудшается читаемость кода

в чём я полностью с тобой согласен!

Так что это палка о двух концах. laughing.gif

Да бог с этими стандартами.
Я попробую компилировать проект сразу в двух компиляторах - IAR и GCC. Хочу сравнить и отписаться об их "узких местах", так как меня это заинтересовало.
Может, ещё кому-то это будет интересно... smile.gif

ЗЫ: вся эта возня с битами снова навела меня на мысль "пощупать" 16-ти битные MSP430. Как-то годик назад я взглянул мельком на несколько мануалов, но показалось, что они послабее периферией универсальных "мег"...
Go to the top of the page
 
+Quote Post
Rst7
сообщение Nov 29 2008, 21:43
Сообщение #79


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

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



Цитата(AHTOXA @ Nov 29 2008, 21:31) *
Но ведь 50% от 0xFFFF - это гораздо больше, чем 50% от 0xFF! smile.gif

Плохо Вы знаете определение вероятности. Вероятность - это отношение количества интересующих состояний к общему количеству состояний. В рассматриваемом случае вероятность одинакова (мелочь не учитываем). А уж абсолютные количества состояний - это совсем другой вопрос. Если выбирается разрядность 8, значит кодер чтото знает о свойствах своих переменных.

А вообще, истоки этого дела (расширение до int) в системе команд PDP-11. Так же, как и описание восьмиричных констант на символ меньше шестнадцатиричных (ребята из DEC'а очень любили восьмиричную систему)

С другой стороны лично я выработал некий набор костылей, которые позволяют писать код, хорошо ложащийся как на AVR, так и на ARM (или на другой 32хбитный камень, да и 16тибитный тоже). В частности, это регулярное применение каста (UREG) и (REG), а сами эти типы определяют размер регистра (например, char для AVR, int для архитектур с более высокой разрядностью). Код, конечно, для неподготовленного человека содержит приличное количество странной писанины, но зато с весьма хорошим результатом после компиляции. Еще один финт - минимизация использования знаковых переменных, т.к. это часто приводит к лишним операциям типа расширения знака.

Кроме того, лично я, например, против современного игнорирования ключевого слова register. Но это отдельный разговор.


--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
Go to the top of the page
 
+Quote Post
sonycman
сообщение Nov 29 2008, 21:56
Сообщение #80


Любитель
*****

Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695



Цитата(Rst7 @ Nov 30 2008, 01:43) *
С другой стороны лично я выработал некий набор костылей, которые позволяют писать код, хорошо ложащийся как на AVR, так и на ARM (или на другой 32хбитный камень, да и 16тибитный тоже). В частности, это регулярное применение каста (UREG) и (REG), а сами эти типы определяют размер регистра (например, char для AVR, int для архитектур с более высокой разрядностью). Код, конечно, для неподготовленного человека содержит приличное количество странной писанины, но зато с весьма хорошим результатом после компиляции. Еще один финт - минимизация использования знаковых переменных, т.к. это часто приводит к лишним операциям типа расширения знака.

Кроме того, лично я, например, против современного игнорирования ключевого слова register. Но это отдельный разговор.


Спасибо за советы smile.gif
Вас, видимо, весьма интересует тема оптимального кода.
Наверное, осталась привычка со времён спектрума?
Мне кажется, сейчас не каждый заглядывает в "недра" бинарников, особенно программеры PC софта.
За отсутствием необходимости? sad.gif

Раскопал ещё один "пережиток стандарта".
Имеем текст:
Код
typedef    unsigned char    byte;
byte percent;
byte    maxRPM;
byte    minRPM;

percent = (maxRPM - minRPM) / 2;

и результат:
Код
            percent = (maxRPM - minRPM) / 2;
     6c0:    80 85           ldd    r24, Z+8; 0x08
     6c2:    90 e0           ldi    r25, 0x00; 0
     6c4:    21 85           ldd    r18, Z+9; 0x09
     6c6:    82 1b           sub    r24, r18
     6c8:    91 09           sbc    r25, r1
     6ca:    62 e0           ldi    r22, 0x02; 2
     6cc:    70 e0           ldi    r23, 0x00; 0
     6ce:    ee d8           rcall    .-3620; 0xfffff8ac <__eeprom_end+0xff7ef884>

Здесь вроде нет знаковых переменных, и нет сложения. Почему не сработала оптимизация?
Разве есть смысл в "запихивании" отрицательного значения в unsigned char? (впрочем, в ИАРе аналогичная фиговина)

Также есть проблемы с утилитой создания листинга avr-objdump - как видно, неправильно вычисляется адрес подпрограммы деления...

Цитата
Цитата
За короткое время знакомства с GCC понравилось: удобная реализация атомарности через макросы ATOMIC_BLOCK(), удобная обёртка для обработчиков прерываний вида ISR(vector_name){}.

Так это как раз не компилятор, это просто библиотечные макросы. Аналогичные макросы можно сделать для любого минимально вменяемого компилятора.

Но разве есть подобные макросы для IAR? Там ведь приходится пользоваться громоздкой конструкцией с pragma и примитивными __disable_interrupt() и __enable_interrupt()...
Go to the top of the page
 
+Quote Post
aesok
сообщение Nov 29 2008, 22:00
Сообщение #81


Знающий
****

Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484



Цитата(sonycman @ Nov 30 2008, 00:02) *
Я попробую компилировать проект сразу в двух компиляторах - IAR и GCC. Хочу сравнить и отписаться об их "узких местах", так как меня это заинтересовало.
Может, ещё кому-то это будет интересно... smile.gif


Мне это будет интересно. Еще интереснее если Вы вооружитесь стандартом на
язык С и выступите в качестве третьего компилятора. Еще, GCC в первую очередь
компилятор стандартного языка С, во вторую компилятор для нескольких
популярных архитектур x86, ARM, 68k и уже в третью - четвертую компилятор для
AVR. Для AVR добавлено много оптимизаций, но всегда есть куда
совершенствоваться. Да но это не значит что на каждое Ваше хочу ктото кудато побежит
чегото делать, какие-то вещи невозможно сделать, какие-то очень трудно, на кикие-то
просто нет времени, а какаето просто не интересно делать. Не забывайте, что Вам никто
ничего не обязан.

Любая конструктивная и обоснованная критика принимается. Не конструктивная,
типа "мне ПОФИГ, что стандарт требует приведения выражения к int, я знаю что
при моих входных параметрах выражение никогда не даст в результате больше 96,
и я ХОЧЮ чтобы компилятор это угадал и использовав при расчетах тип char"
меня не интересует.

К сожалению в мои таланты не входит просто и доходчиво учить и разъяснять
положения стандарта и занимаюсь я этим очень редко и неохотно.

Это ссылка на стандарт: www.open-std.org/JTC1/SC22/WG14/www/docs/n1124.pdf

С уважением,
Анатолий.
Go to the top of the page
 
+Quote Post
sonycman
сообщение Nov 29 2008, 22:24
Сообщение #82


Любитель
*****

Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695



Цитата(aesok @ Nov 30 2008, 02:00) *
Не забывайте, что Вам никто
ничего не обязан.

Я разве здесь хоть что-то от кого-то потребовал?
Просто привожу вещи, которые мне непонятны/кажутся глупыми/достойными восхищения и т.д. и т.п.
И премного благодарен всем, кто наставляет меня "на путь истинный" a14.gif
И, вероятнее всего, не только меня.

Цитата
мне ПОФИГ, что стандарт требует приведения выражения к int, я знаю что
при моих входных параметрах выражение никогда не даст в результате больше 96,
и я ХОЧЮ чтобы компилятор это угадал и использовав при расчетах тип char

Если вы не поняли, то весь смысл про char был в одном - применительно к AVR это неудобно и неэффективно. С моей точки зрения. Никому её не навязываю и тем более никого не убеждаю изменять стандарты smile.gif
А вот доводить до ума оптимизацию, думаю, нужно. В частности, по обработке switch?
Go to the top of the page
 
+Quote Post
Rst7
сообщение Nov 29 2008, 22:24
Сообщение #83


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

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



Цитата(aesok @ Nov 30 2008, 00:00) *
меня не интересует.

Простите, а Вы участвуете в разработке GCC, в частности для AVR?

Если да, то у меня есть конструктивная критика. Изложена она в ветке про сборки klen'а. Это Вас заинтересует? Или обычный ответ - "никто никому ничего не должен?" wink.gif


--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
Go to the top of the page
 
+Quote Post
aesok
сообщение Nov 29 2008, 22:36
Сообщение #84


Знающий
****

Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484



Цитата(Rst7 @ Nov 30 2008, 01:24) *
Простите, а Вы участвуете в разработке GCC, в частности для AVR?


Да.

Цитата(Rst7 @ Nov 30 2008, 01:24) *
Если да, то у меня есть конструктивная критика. Изложена она в ветке про сборки klen'а. Это Вас заинтересует? Или обычный ответ - "никто никому ничего не должен?" wink.gif


К сожалению ответ тоже, да. Идей и багов намного больше чем времени на них.

Анатолий.
Go to the top of the page
 
+Quote Post
Rst7
сообщение Nov 29 2008, 22:53
Сообщение #85


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

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



Цитата(sonycman @ Nov 29 2008, 23:56) *
Там ведь приходится пользоваться громоздкой конструкцией с pragma и примитивными __disable_interrupt() и __enable_interrupt()...

Дык гдето в соседней ветке (кажется, "За что я не люблю Си") ктото привел макрос критической секции из цикла for, а я дальше выложил его вариант для IAR'а, с учетом его встроенных intrinsinc'ов. Кстати, есть еще в IAR'е всякие полезности типа __monitor, __save_interrupt и __restore_interrupt. Так что все не так плохо smile.gif

Цитата(aesok @ Nov 30 2008, 00:36) *
К сожалению ответ тоже, да.

Я так и думал. Очень жаль. На самом деле внесенный баг весьма серьезен.

Вынужден констатировать, что многие опенсорсные проекты в конце концов превращаются в "жрите что дают". Да еще и морально подпитываются говнопиаром класса "халява рулит" sad.gif

За сим откланиваюсь. Было приятно освежить в памяти подзабытые вещи благодаря конструктивной беседе с Вами.


--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
Go to the top of the page
 
+Quote Post
sonycman
сообщение Nov 29 2008, 23:14
Сообщение #86


Любитель
*****

Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695



Цитата(Rst7 @ Nov 30 2008, 02:53) *
Дык гдето в соседней ветке (кажется, "За что я не люблю Си") ктото привел макрос критической секции из цикла for, а я дальше выложил его вариант для IAR'а, с учетом его встроенных intrinsinc'ов. Кстати, есть еще в IAR'е всякие полезности типа __monitor, __save_interrupt и __restore_interrupt. Так что все не так плохо smile.gif

1. Посмотрю обязательно.
2. __monitor я и юзал. Жаль, что он работает только ко всей функции...

В ИАРе очень удобно сделана работа с указателями на память программ и eeprom. Она совершенно не отличается от указателей на оперативку a14.gif
Хотелось бы видеть такое когда-нибудь и в GCC.
Go to the top of the page
 
+Quote Post
AHTOXA
сообщение Nov 29 2008, 23:23
Сообщение #87


фанат дивана
******

Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684



Цитата(Rst7 @ Nov 30 2008, 02:43) *
Плохо Вы знаете определение вероятности.

Это да, еле-еле сдал на троечку 05.gif Но! Самой тётушке Вентцель yeah.gif
Зато в процентах я силёнsmile.gif


--------------------
Если бы я знал, что такое электричество...
Go to the top of the page
 
+Quote Post
aesok
сообщение Nov 29 2008, 23:31
Сообщение #88


Знающий
****

Группа: Участник
Сообщений: 596
Регистрация: 26-05-06
Из: Москва
Пользователь №: 17 484



Цитата(Rst7 @ Nov 30 2008, 01:53) *
Вынужден констатировать, что многие опенсорсные проекты в конце концов превращаются в "жрите что дают".


Во первых да, Вы правы:
Код
$ avr-gcc --version
avr-gcc (GCC) 4.4.0 20081129 (experimental)
Copyright (C) 2008 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Дословный перевод этого и есть: "жрите что дают".

Во вторых, Вы ничего не платили и поэтому ничего не вправе требовать, только ждать пока сделают что Вам нужно или сделать сам. Я делаю только то что интересно и нужно мне.

Цитата(Rst7 @ Nov 30 2008, 01:53) *
Да еще и морально подпитываются говнопиаром класса "халява рулит" sad.gif


Я могу ответить только за себя. Я НИКОГДА не занимался пиаром свободного софта. ВЫ не найдете ни одного моего призыва чем то пользаваться а чем то нет.

Мой выбор очень прост, Я пытаюсь решить задачу наиболее простым и эффективным способом, если для этого нужен коммерческий софт, я ипользую его, если лучше подходит свободный софт, я его применяю.

Анатолий.

PS: Для чего я этим занимаюсь, Вас не касается.

Сообщение отредактировал aesok - Nov 29 2008, 23:59
Go to the top of the page
 
+Quote Post
sonycman
сообщение Nov 30 2008, 10:23
Сообщение #89


Любитель
*****

Группа: Свой
Сообщений: 1 864
Регистрация: 20-08-06
Из: Тольятти
Пользователь №: 19 695



Неважнецки получается у GCC работа со структурой в нижеприведённой функции.
Обработчик прерывания usart:
Код
typedef    unsigned char    byte;

struct    usart_rx_status
{
    byte    counter;
    byte    mode;
    volatile bool data_available;
    bool    frame_err;
    bool    ovrun_err;
    bool    parity_err;
    bool    length_err;
    bool    lock_err;
    bool    chksum_err;
    bool    unknown_command;
} statusRx;

ISR(USART_RX_vect)
{
    static    byte    sign[] PROGMEM =    {'S','N'};
    static    byte    length;
    byte    data, state;

    do
    {
        state    =    UCSR0A;
        data    =    UDR0;
        if (statusRx.data_available)
            {
                statusRx.lock_err    =    TRUE;
                continue;
            }
        if (state & ((1<<FE0)|(1<<DOR0)|(1<<UPE0)))
        {
            if (state & (1<<FE0)) statusRx.frame_err    =    TRUE;
            if (state & (1<<DOR0)) statusRx.ovrun_err    =    TRUE;
            if (state & (1<<UPE0)) statusRx.parity_err    =    TRUE;
            statusRx.mode    =    RX_SEEK;
            statusRx.counter    =    0;
            continue;
        }
        else
        {
            statusRx.frame_err    =    0;
            statusRx.ovrun_err    =    0;
            statusRx.parity_err    =    0;
            statusRx.length_err    =    0;
            statusRx.lock_err    =    0;
            statusRx.chksum_err    =    0;
        }
        switch(statusRx.mode)
        {
        case    RX_SEEK:
            if (statusRx.counter < sizeof(sign))
            {
                if (data == pgm_read_byte(sign[statusRx.counter]))
                {
                    statusRx.counter++;
                }
                else
                {
                    statusRx.counter    =    0;
                }
            }
            else
            {
                statusRx.counter    =    0;
                if (data    >= sizeof(rx_buffer) || data == 0)
                {
                    statusRx.length_err    =    TRUE;
                    break;
                }
                rx_buffer[statusRx.counter++]    =    data;
                length    =    ++data;
                statusRx.mode    =    RX_RUNNING;
            }
            break;
        case    RX_RUNNING:
            rx_buffer[statusRx.counter++]    =    data;
            length--;
            if (!length)
            {
                statusRx.data_available    =    TRUE;
                statusRx.mode    =    RX_SEEK;
                statusRx.counter    =    0;
            }
            break;
        }

    }while(UCSR0A & (1<<RXC0));
}

Вот результат:
Код
ISR(USART_RX_vect)
     b10:    1f 92           push    r1
     b12:    0f 92           push    r0
     b14:    0f b6           in    r0, 0x3f; 63
     b16:    0f 92           push    r0
     b18:    11 24           eor    r1, r1
     b1a:    0f 93           push    r16
     b1c:    1f 93           push    r17
     b1e:    2f 93           push    r18
     b20:    3f 93           push    r19
     b22:    4f 93           push    r20
     b24:    5f 93           push    r21
     b26:    6f 93           push    r22
     b28:    7f 93           push    r23
     b2a:    8f 93           push    r24
     b2c:    9f 93           push    r25
     b2e:    af 93           push    r26
     b30:    bf 93           push    r27
     b32:    ef 93           push    r30
     b34:    ff 93           push    r31
     b36:    00 91 8d 01     lds    r16, 0x018D
     b3a:    b0 91 9b 01     lds    r27, 0x019B
     b3e:    f0 91 99 01     lds    r31, 0x0199
     b42:    e0 91 98 01     lds    r30, 0x0198
     b46:    70 91 97 01     lds    r23, 0x0197
     b4a:    60 91 96 01     lds    r22, 0x0196
     b4e:    50 91 93 01     lds    r21, 0x0193
     b52:    10 91 94 01     lds    r17, 0x0194
     b56:    40 91 9a 01     lds    r20, 0x019A
//    errorRx.allbits    =    0;
    byte    data, state;

    do
    {
        state    =    UCSR0A;
     b5a:    90 91 c0 00     lds    r25, 0x00C0
        data    =    UDR0;
     b5e:    a0 91 c6 00     lds    r26, 0x00C6
        if (statusRx.data_available)
     b62:    80 91 95 01     lds    r24, 0x0195
     b66:    88 23           and    r24, r24
     b68:    11 f0           breq    .+4; 0xb6e <__vector_18+0x5e>
     b6a:    41 e0           ldi    r20, 0x01; 1
     b6c:    54 c0           rjmp    .+168; 0xc16 <__vector_18+0x106>
            {
                statusRx.lock_err    =    TRUE;
                continue;
            }
        if (state & ((1<<FE0)|(1<<DOR0)|(1<<UPE0)))
     b6e:    29 2f           mov    r18, r25
     b70:    30 e0           ldi    r19, 0x00; 0
     b72:    c9 01           movw    r24, r18
     b74:    8c 71           andi    r24, 0x1C; 28
     b76:    90 70           andi    r25, 0x00; 0
     b78:    89 2b           or    r24, r25
     b7a:    49 f0           breq    .+18; 0xb8e <__vector_18+0x7e>
        {
            if (state & (1<<FE0)) statusRx.frame_err    =    TRUE;
     b7c:    24 fd           sbrc    r18, 4
     b7e:    61 e0           ldi    r22, 0x01; 1
            if (state & (1<<DOR0)) statusRx.ovrun_err    =    TRUE;
     b80:    23 fd           sbrc    r18, 3
     b82:    71 e0           ldi    r23, 0x01; 1
            if (state & (1<<UPE0)) statusRx.parity_err    =    TRUE;
     b84:    22 fd           sbrc    r18, 2
     b86:    e1 e0           ldi    r30, 0x01; 1
     b88:    50 e0           ldi    r21, 0x00; 0
     b8a:    10 e0           ldi    r17, 0x00; 0
     b8c:    44 c0           rjmp    .+136; 0xc16 <__vector_18+0x106>
            statusRx.length_err    =    0;
            statusRx.lock_err    =    0;
            statusRx.chksum_err    =    0;
        }
//        lcdPrintByte(data, 0, 0);
        switch(statusRx.mode)
     b8e:    11 23           and    r17, r17
     b90:    19 f0           breq    .+6; 0xb98 <__vector_18+0x88>
     b92:    11 30           cpi    r17, 0x01; 1
     b94:    d1 f5           brne    .+116; 0xc0a <__vector_18+0xfa>
     b96:    27 c0           rjmp    .+78; 0xbe6 <__vector_18+0xd6>
        {
        case    RX_SEEK:
            if (statusRx.counter < sizeof(sign))
     b98:    52 30           cpi    r21, 0x02; 2
     b9a:    70 f4           brcc    .+28; 0xbb8 <__vector_18+0xa8>
            {
                if (data == pgm_read_byte(sign[statusRx.counter]))
     b9c:    e5 2f           mov    r30, r21
     b9e:    f0 e0           ldi    r31, 0x00; 0
     ba0:    ec 5c           subi    r30, 0xCC; 204
     ba2:    ff 4f           sbci    r31, 0xFF; 255
     ba4:    e0 81           ld    r30, Z
     ba6:    f0 e0           ldi    r31, 0x00; 0
     ba8:    e4 91           lpm    r30, Z+
     baa:    ae 17           cp    r26, r30
     bac:    19 f0           breq    .+6; 0xbb4 <__vector_18+0xa4>
     bae:    b0 e0           ldi    r27, 0x00; 0
     bb0:    f0 e0           ldi    r31, 0x00; 0
     bb2:    08 c0           rjmp    .+16; 0xbc4 <__vector_18+0xb4>
                {
                    statusRx.counter++;
     bb4:    5f 5f           subi    r21, 0xFF; 255
     bb6:    29 c0           rjmp    .+82; 0xc0a <__vector_18+0xfa>
                }
            }
            else
            {
                statusRx.counter    =    0;
                if (data    >= sizeof(rx_buffer) || data == 0)
     bb8:    8a 2f           mov    r24, r26
     bba:    81 50           subi    r24, 0x01; 1
     bbc:    8f 31           cpi    r24, 0x1F; 31
     bbe:    38 f0           brcs    .+14; 0xbce <__vector_18+0xbe>
     bc0:    b0 e0           ldi    r27, 0x00; 0
     bc2:    f1 e0           ldi    r31, 0x01; 1
     bc4:    e0 e0           ldi    r30, 0x00; 0
     bc6:    70 e0           ldi    r23, 0x00; 0
     bc8:    60 e0           ldi    r22, 0x00; 0
     bca:    50 e0           ldi    r21, 0x00; 0
     bcc:    23 c0           rjmp    .+70; 0xc14 <__vector_18+0x104>
                {
                    statusRx.length_err    =    TRUE;
                    break;
                }
                rx_buffer[statusRx.counter++]    =    data;
     bce:    a0 93 a1 01     sts    0x01A1, r26
                length    =    ++data;
     bd2:    0a 2f           mov    r16, r26
     bd4:    0f 5f           subi    r16, 0xFF; 255
     bd6:    b0 e0           ldi    r27, 0x00; 0
     bd8:    f0 e0           ldi    r31, 0x00; 0
     bda:    e0 e0           ldi    r30, 0x00; 0
     bdc:    70 e0           ldi    r23, 0x00; 0
     bde:    60 e0           ldi    r22, 0x00; 0
     be0:    51 e0           ldi    r21, 0x01; 1
     be2:    11 e0           ldi    r17, 0x01; 1
     be4:    17 c0           rjmp    .+46; 0xc14 <__vector_18+0x104>
//                lcdPrintByte(data, 0, 1);
                statusRx.mode    =    RX_RUNNING;
            }
            break;
        case    RX_RUNNING:
            rx_buffer[statusRx.counter++]    =    data;
     be6:    e5 2f           mov    r30, r21
     be8:    f0 e0           ldi    r31, 0x00; 0
     bea:    ef 55           subi    r30, 0x5F; 95
     bec:    fe 4f           sbci    r31, 0xFE; 254
     bee:    a0 83           st    Z, r26
     bf0:    5f 5f           subi    r21, 0xFF; 255
            length--;
     bf2:    01 50           subi    r16, 0x01; 1
            if (!length)
     bf4:    51 f4           brne    .+20; 0xc0a <__vector_18+0xfa>
            {
                statusRx.data_available    =    TRUE;
     bf6:    10 93 95 01     sts    0x0195, r17
     bfa:    b0 e0           ldi    r27, 0x00; 0
     bfc:    f0 e0           ldi    r31, 0x00; 0
     bfe:    e0 e0           ldi    r30, 0x00; 0
     c00:    70 e0           ldi    r23, 0x00; 0
     c02:    60 e0           ldi    r22, 0x00; 0
     c04:    50 e0           ldi    r21, 0x00; 0
     c06:    10 e0           ldi    r17, 0x00; 0
     c08:    05 c0           rjmp    .+10; 0xc14 <__vector_18+0x104>
     c0a:    b0 e0           ldi    r27, 0x00; 0
     c0c:    f0 e0           ldi    r31, 0x00; 0
     c0e:    e0 e0           ldi    r30, 0x00; 0
     c10:    70 e0           ldi    r23, 0x00; 0
     c12:    60 e0           ldi    r22, 0x00; 0
     c14:    40 e0           ldi    r20, 0x00; 0
//    statusRx.mode    =    RX_SEEK;
//    statusRx.data_available    =    0;
//    errorRx.allbits    =    0;
    byte    data, state;

    do
     c16:    80 91 c0 00     lds    r24, 0x00C0
     c1a:    87 fd           sbrc    r24, 7
     c1c:    9e cf           rjmp    .-196; 0xb5a <__vector_18+0x4a>
     c1e:    00 93 8d 01     sts    0x018D, r16
     c22:    b0 93 9b 01     sts    0x019B, r27
     c26:    f0 93 99 01     sts    0x0199, r31
     c2a:    e0 93 98 01     sts    0x0198, r30
     c2e:    70 93 97 01     sts    0x0197, r23
     c32:    60 93 96 01     sts    0x0196, r22
     c36:    50 93 93 01     sts    0x0193, r21
     c3a:    10 93 94 01     sts    0x0194, r17
     c3e:    40 93 9a 01     sts    0x019A, r20
            }
            break;
        }

    }while(UCSR0A & (1<<RXC0));
}
     c42:    ff 91           pop    r31
     c44:    ef 91           pop    r30
     c46:    bf 91           pop    r27
     c48:    af 91           pop    r26
     c4a:    9f 91           pop    r25
     c4c:    8f 91           pop    r24
     c4e:    7f 91           pop    r23
     c50:    6f 91           pop    r22
     c52:    5f 91           pop    r21
     c54:    4f 91           pop    r20
     c56:    3f 91           pop    r19
     c58:    2f 91           pop    r18
     c5a:    1f 91           pop    r17
     c5c:    0f 91           pop    r16
     c5e:    0f 90           pop    r0
     c60:    0f be           out    0x3f, r0; 63
     c62:    0f 90           pop    r0
     c64:    1f 90           pop    r1
     c66:    18 95           reti

344 байта.

У ИАРа тот-же код занимает 278 байт...
Go to the top of the page
 
+Quote Post
Rst7
сообщение Nov 30 2008, 11:09
Сообщение #90


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

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



Хоть я и откланялся, но господину sonycman'у отвечу, потому как тема имеет тенденцию сдвигаться в немного другую область, нежели IAR vs GCC.

Цитата
Неважнецки получается у GCC работа со структурой в нижеприведённой функции.


Вообщем-то философия оптимизации данной функции гнусем понятна - загрузить в регистры все что можно и на выходе выгрузить. Подход правильный, основанный на общей идеологии RISC и Load-Store. Но в данном случае он немного не оправдывает себя.

IAR подходит к проблеме утилизации Load-Store с более сдержанных позиций, он выполняет эти операции в более локальной окрестности действий с полями структуры. С другой стороны, это позволяет кодеру помочь компилятору в ручном указании, какие переменные стоит загрузить в самом начале (и сохранить в самом конце), какие - нет. Я пришел к следующей эмпирической оценке - оцениваю количество обращений к переменной. Если их больше 3, то имеет смысл переносить переменную в регистр. Причем, чем больше обращений (с учетом циклов), тем выше приоритет переменной на перенос в регистр. Ну и не забывать, что операция a=b++ - суть 2 обращения, а иногда и 3.

Можно ли так подсказать гнусю - я затрудняюсь ответить, необходимо проверять.

Кроме того, я бы флаги ошибок собрал бы в битовой структуре. Так проще. В результате, получился бы примерно следующий код (IAR)
Код
typedef struct
{
  byte    frame_err:1,ovrun_err:1,parity_err:1,length_err:1,lock_err:1,chksum_err:1,unknown_command:1;
} USART_ERRORS;

struct    usart_rx_status
{
  byte    counter;
  byte    mode;
  volatile byte data_available;
  USART_ERRORS err;
} statusRx;

#pragma vector=USART_RX_vect
__interrupt void ISR_USART_RX(void)
{
  static    __flash byte    sign[] =    {'S','N'};
  static    byte    save_length;
  byte    data, state;
  USART_ERRORS err=statusRx.err;
  byte length=save_length;
  byte counter=statusRx.counter;
  
  do
  {
    state    =    UCSR0A;
    data    =    UDR0;
    if (statusRx.data_available)
    {
      err.lock_err    =    TRUE;
      continue;
    }
    if (state & ((1<<FE0)|(1<<DOR0)|(1<<UPE0)))
    {
      if (state & (1<<FE0)) err.frame_err    =    TRUE;
      if (state & (1<<DOR0)) err.ovrun_err    =    TRUE;
      if (state & (1<<UPE0)) err.parity_err    =    TRUE;
      statusRx.mode    =    RX_SEEK;
      counter    =    0;
      continue;
    }
    else
    {
      err.frame_err    =    0;
      err.ovrun_err    =    0;
      err.parity_err    =    0;
      err.length_err    =    0;
      err.lock_err    =    0;
      err.chksum_err    =    0;
    }
    switch(statusRx.mode)
    {
    case    RX_SEEK:
      if (counter < sizeof(sign))
      {
    if (data == sign[counter])
    {
      counter++;
    }
    else
    {
      counter    =    0;
    }
      }
      else
      {
    counter    =    0;
    if (data    >= sizeof(rx_buffer) || data == 0)
    {
      err.length_err    =    TRUE;
      break;
    }
    rx_buffer[counter++]    =    data;
    length    =    ++data;
    statusRx.mode    =    RX_RUNNING;
      }
      break;
    case    RX_RUNNING:
      rx_buffer[counter++]    =    data;
      length--;
      if (!length)
      {
    statusRx.data_available    =    TRUE;
    statusRx.mode    =    RX_SEEK;
    counter    =    0;
      }
      break;
    }
    
  }while(UCSR0A & (1<<RXC0));
  save_length=length;
  statusRx.err=err;
  statusRx.counter=counter;
}


и результат

Код
//   27 __interrupt void ISR_USART_RX(void)
ISR_USART_RX:
//   28 {
        ST      -Y, R27
        ST      -Y, R26
        ST      -Y, R31
        ST      -Y, R30
        ST      -Y, R22
        ST      -Y, R21
        ST      -Y, R20
        ST      -Y, R19
        ST      -Y, R18
        ST      -Y, R17
        ST      -Y, R16
        IN      R22, 0x3F
//   29   static    __flash byte    sign[] =    {'S','N'};
//   30   static    byte    save_length;
//   31   byte    data, state;
//   32   USART_ERRORS err=statusRx.err;
        LDI     R26, LOW(statusRx)
        LDI     R27, (statusRx) >> 8
        MOVW    R31:R30, R27:R26
        LDD     R16, Z+3
//   33   byte length=save_length;
        LDD     R19, Z+4
//   34   byte counter=statusRx.counter;
        LD      R18, X
//   35  
//   36   do
//   37   {
//   38     state    =    UCSR0A;
??ISR_USART_RX_0:
        LDS     R21, 192
//   39     data    =    UDR0;
        LDS     R17, 198
//   40     if (statusRx.data_available)
        MOVW    R31:R30, R27:R26
        LDD     R20, Z+2
        TST     R20
        BREQ    ??ISR_USART_RX_1
//   41     {
//   42       err.lock_err    =    TRUE;
        ORI     R16, 0x10
//   43       continue;
        RJMP    ??ISR_USART_RX_2
//   44     }
//   45     if (state & ((1<<FE0)|(1<<DOR0)|(1<<UPE0)))
??ISR_USART_RX_1:
        MOV     R20, R21
        ANDI    R20, 0x1C
        BREQ    ??ISR_USART_RX_3
//   46     {
//   47       if (state & (1<<FE0)) err.frame_err    =    TRUE;
        BST     R21, 4
        BRTC    ??ISR_USART_RX_4
        ORI     R16, 0x01
//   48       if (state & (1<<DOR0)) err.ovrun_err    =    TRUE;
??ISR_USART_RX_4:
        BST     R21, 3
        BRTC    ??ISR_USART_RX_5
        ORI     R16, 0x02
//   49       if (state & (1<<UPE0)) err.parity_err    =    TRUE;
??ISR_USART_RX_5:
        BST     R21, 2
        BRTC    ??ISR_USART_RX_6
        ORI     R16, 0x04
//   50       statusRx.mode    =    RX_SEEK;
        RJMP    ??ISR_USART_RX_6
//   51       counter    =    0;
//   52       continue;
//   53     }
//   54     else
//   55     {
//   56       err.frame_err    =    0;
//   57       err.ovrun_err    =    0;
//   58       err.parity_err    =    0;
//   59       err.length_err    =    0;
//   60       err.lock_err    =    0;
//   61       err.chksum_err    =    0;
??ISR_USART_RX_3:
        ANDI    R16, 0xC0
//   62     }
//   63     switch(statusRx.mode)
        LDD     R20, Z+1
        SUBI    R20, 0
        BREQ    ??ISR_USART_RX_7
        DEC     R20
        BREQ    ??ISR_USART_RX_8
        RJMP    ??ISR_USART_RX_2
//   64     {
//   65     case    RX_SEEK:
//   66       if (counter < sizeof(sign))
??ISR_USART_RX_7:
        CPI     R18, 2
        BRCC    ??ISR_USART_RX_9
//   67       {
//   68     if (data == sign[counter])
        LDI     R31, 0
        MOV     R30, R18
        SUBI    R30, LOW((-(??sign) & 0xFFFF))
        SBCI    R31, (-(??sign) & 0xFFFF) >> 8
        LPM     R20, Z
        CP      R17, R20
        BRNE    ??ISR_USART_RX_10
//   69     {
//   70       counter++;
        INC     R18
        RJMP    ??ISR_USART_RX_2
//   71     }
//   72     else
//   73     {
//   74       counter    =    0;
//   75     }
//   76       }
//   77       else
//   78       {
//   79     counter    =    0;
??ISR_USART_RX_9:
        LDI     R18, 0
//   80     if (data    >= sizeof(rx_buffer) || data == 0)
        CPI     R17, 100
        BRCC    ??ISR_USART_RX_11
        TST     R17
        BRNE    ??ISR_USART_RX_12
//   81     {
//   82       err.length_err    =    TRUE;
??ISR_USART_RX_11:
        ORI     R16, 0x08
//   83       break;
        RJMP    ??ISR_USART_RX_2
//   84     }
//   85     rx_buffer[counter++]    =    data;
??ISR_USART_RX_12:
        STS     rx_buffer, R17
        LDI     R18, 1
//   86     length    =    ++data;
        MOV     R19, R17
        INC     R19
//   87     statusRx.mode    =    RX_RUNNING;
        STD     Z+1, R18
        RJMP    ??ISR_USART_RX_2
//   88       }
//   89       break;
//   90     case    RX_RUNNING:
//   91       rx_buffer[counter++]    =    data;
??ISR_USART_RX_8:
        LDI     R31, 0
        MOV     R30, R18
        SUBI    R30, LOW((-(rx_buffer) & 0xFFFF))
        SBCI    R31, (-(rx_buffer) & 0xFFFF) >> 8
        ST      Z, R17
        INC     R18
//   92       length--;
        DEC     R19
//   93       if (!length)
        TST     R19
        BRNE    ??ISR_USART_RX_2
//   94       {
//   95     statusRx.data_available    =    TRUE;
        LDI     R17, 1
        MOVW    R31:R30, R27:R26
        STD     Z+2, R17
//   96     statusRx.mode    =    RX_SEEK;
??ISR_USART_RX_6:
        LDI     R17, 0
        STD     Z+1, R17
//   97     counter    =    0;
??ISR_USART_RX_10:
        LDI     R18, 0
//   98       }
//   99       break;
//  100     }
//  101    
//  102   }while(UCSR0A & (1<<RXC0));
??ISR_USART_RX_2:
        LDS     R17, 192
        SBRC    R17, 7
        RJMP    ??ISR_USART_RX_0
//  103   save_length=length;
        MOVW    R31:R30, R27:R26
        STD     Z+4, R19
//  104   statusRx.err=err;
        STD     Z+3, R16
//  105   statusRx.counter=counter;
        ST      X, R18
//  106 }
        OUT     0x3F, R22
        LD      R16, Y+
        LD      R17, Y+
        LD      R18, Y+
        LD      R19, Y+
        LD      R20, Y+
        LD      R21, Y+
        LD      R22, Y+
        LD      R30, Y+
        LD      R31, Y+
        LD      R26, Y+
        LD      R27, Y+
        RETI

....
// 218 bytes in segment CODE


Попробуйте сделать аналогичный финт с гнусем, посмотрим, как он себя поведет.


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

10 страниц V  « < 4 5 6 7 8 > » 
Reply to this topicStart new topic
3 чел. читают эту тему (гостей: 3, скрытых пользователей: 0)
Пользователей: 0

 


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


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