|
|
  |
"Оптимизация" в WinAVR и как с этим бороться |
|
|
|
Nov 28 2011, 14:16
|

Нечётный пользователь.
     
Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417

|
Цитата(MaxiMuz @ Nov 28 2011, 12:59)  подобен коду сформированному с использованием регистровых переменных: Код if (!(--FLCnt)) 2e: 80 2f mov r24, r16 30: 81 50 subi r24, 0x01; 1 32: 08 2f mov r16, r24 34: 11 f4 brne .+4 Но даже если закрыть глаза на бессмысленные mov rd,rs , как вы сами признали чуть быстрее и меньше по коду. Но всё равно проиграет чисто-асмовой реализации гораздо больше, чем выиграет у «универсальной» реализации («универсальной» в том смысле, что точно так же можно написать для IAR/MSP430 и оно тоже будет оптимально в плане работы с volatile-переменными в памяти). Цитата(MaxiMuz @ Nov 28 2011, 12:59)  И в использование возможностей железа по максимуму, даже учитывая корявость компилятора, нет ничего предосудительного  А абстрагирование от железа приводит к появлению таких опусов как Win7 ! с неоправданно раздутым кодом и тормозным ядром! А абстрагирование от языка и компилятора к чему приводит? Сначала нужно навчиться по-максимуму использовать платформенно-независимые возможности языка, а то получается «вперёд к коммунизму минуя феодализм». А уже потом использовать учиться использовать возможности специфического компилятора для доступа к специфическим возможностям железа. Если ставить телегу впереди лошади, то выходит как у Вас — оно-то вроде и короче, но для того, чтобы оно заработало правильно, приходится делать костыли в виде отдельно вызываемой функции инициализации этих переменных (rcall+ret сожрали 4 байта из выигрыша варианта без принудительно-регистровых переменных). А там, глядишь, и в других местах для нормального обращения к этим переменным придётся городить функции. Цитата(MaxiMuz @ Nov 28 2011, 12:59)  Код if ( GPIOR0 & DbRKey ) кстати в ATtiny13 (под него я пишу код) нет таких регистров вв./выв. которые можно так использовать! с вами полностью согласен , но гибкое использование железа тоже часть "знания Си" Нет. Это часть знания аппаратуры, а не языка. Эти же GPIOR можно и из ассемблера использовать, и из бейсика и что там ещё для AVR найдётся. В теме до сих пор упоминался только ATtiny2313, у которого их три, вот я как-то и отнёс всё остальное к нему.
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
|
Nov 28 2011, 20:17
|

Нечётный пользователь.
     
Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417

|
Для этого в AVR-GCC уже давно есть OS_main и OS_task, они что-то там глубже копают. Если main() сама по себе довольно большая, то OS_main даст больше эффекта, чем noreturn. ... Начиная с 4.2.2, если верить мне самому в исходниках порта scmRTOS :-) Код #if GCC_VERSION >= 40202 #define OS_PROCESS __attribute__((OS_task)) #else #define OS_PROCESS __attribute__((__noreturn__)) #endif
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
|
Jan 23 2012, 09:15
|

Местный
  
Группа: Участник
Сообщений: 253
Регистрация: 15-04-10
Из: Волгоград
Пользователь №: 56 658

|
Цитата(sigmaN @ Nov 28 2011, 22:40)  перед main воткните __attribute__ ((noreturn)); http://www.emerson.emory.edu/services/gcc/...Attributes.htmlэкономит "пару" байт Никакого действия этот предписание на программу не оказало, и я не понял из описания на что оно конкретно делает.
|
|
|
|
|
Jan 23 2012, 09:53
|

Профессионал
    
Группа: Свой
Сообщений: 1 143
Регистрация: 30-09-08
Из: Новочеркасск
Пользователь №: 40 581

|
Цитата(ILYAUL @ Nov 29 2011, 08:15)  ИМХО . Для 13 писать на С , можно только в рамках изучения С , там и asm сложно "развернуться", если задействовать все ее ресурсы. не согласен. во-первых, все ресурсы МК вообще сложно задействовать одновременно (в одном проекте то есть), даже если МК "просторнее" тини13. а во-вторых, я лично последние годы пишу только на Си, причем для тини13 сделал несколько разных проектов, часто даже не напрягаясь с оптимизацией. последний проект - RGB-светильник с дистанционным управлением (пульт ДУ тоже на тини13)  на Си пишется достаточно комфортно.
--------------------
Я бы взял частями... но мне надо сразу.
|
|
|
|
|
Feb 2 2012, 11:49
|

Местный
  
Группа: Участник
Сообщений: 253
Регистрация: 15-04-10
Из: Волгоград
Пользователь №: 56 658

|
Цитата(sigmaN @ Jan 24 2012, 05:07)  warning это не error и по идее не должен приводить к трудностям с hex файлом. no return statement in function returning non-void подсказывает вам, что функцию вы объявили как возвращающую значение(т.е. не void) а return в теле функции не встречается. Самое простое: добавить в функцию return 0; добавил в конец функции int OS_main (void) оператор return 0; предупреждение пропало, но ошибка линковщика , которую я в начале не заметил осталась : Код inking: copy_reg_struct.elf avr-gcc -mmcu=attiny13a -I. -gdwarf-2 -DF_CPU=8000000UL -Os -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall -Wstrict-prototypes -Wa,-adhlns=copy_reg_struct.o -std=gnu99 -MMD -MP -MF .dep/copy_reg_struct.elf.d copy_reg_struct.o --output copy_reg_struct.elf -Wl,-Map=copy_reg_struct.map,--cref,-gc-sections -lm c:/program files/winavr-20100110/bin/../lib/gcc/avr/4.3.3/../../../../avr/lib/avr25/crttn13a.o:(.init9+0x0): undefined reference to `main' make.exe: *** [copy_reg_struct.elf] Error 1
|
|
|
|
|
Feb 3 2012, 10:42
|

Местный
  
Группа: Участник
Сообщений: 253
Регистрация: 15-04-10
Из: Волгоград
Пользователь №: 56 658

|
Цитата(_Pasha @ Feb 2 2012, 15:16)  Таварисч не панимаит. Код int main(void) __attribute__((OS_main)) { // blabla return 0; } Да! я не поимаю! в этом случае компил. кажет: Код copy_reg_struct.c:112: error: expected ',' or ';' before '{' token
|
|
|
|
|
Feb 3 2012, 11:08
|

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

|
QUOTE (MaxiMuz @ Feb 3 2012, 12:42)  Да! я не поимаю! _Pasha описАлся. CODE __attribute__((OS_main)) int main(void) { // blabla return 0; } или CODE int main(void) __attribute__((OS_main));
int main(void) { // blabla return 0; } И не спрашивайте "почему?". Так есть.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Oct 16 2012, 18:35
|

Местный
  
Группа: Участник
Сообщений: 253
Регистрация: 15-04-10
Из: Волгоград
Пользователь №: 56 658

|
Доброго времяни суток! Не стал создавать отдельной темы. Хочу прояснить для себя такой момент, фрагмент: Код #define Mask (0x07) int main (void) { uint8_t Cnt=0; while (1) { if (Cnt &((unsigned char) Mask)) {Buf1=1; } else { Buf1=2; } Cnt++; } } Где условие компилируется в: Код if (Cnt &((unsigned char) Mask)) 56: 82 2f mov r24, r18 58: 90 e0 ldi r25, 0x00; 0 5a: 87 70 andi r24, 0x07; 7 5c: 90 70 andi r25, 0x00; 0 5e: 89 2b or r24, r25 60: 19 f0 breq .+6 ; 0x68 <main+0x1c> здесь игнорирование (unsigned char) перед Mask это особенности GCC компилятора ? Т.к. AVR 8ми битный, можно ли отключить както 16битное расширение ?
Сообщение отредактировал MaxiMuz - Oct 16 2012, 18:37
|
|
|
|
|
Oct 16 2012, 19:26
|

Профессионал
    
Группа: Участник
Сообщений: 1 620
Регистрация: 22-06-07
Из: Санкт-Петербург, Россия
Пользователь №: 28 634

|
Используйте компилятор поновее (avr-gcc 4.7.2, avr-gcc 4.8) - будет Вам счастье (на моих проектах объём кода на 30% уменьшился): Код 0000007c <main>: 7c: 80 e0 ldi r24, 0x00; 0 7e: 92 e0 ldi r25, 0x02; 2 80: 21 e0 ldi r18, 0x01; 1 82: 37 e0 ldi r19, 0x07; 7 84: 38 23 and r19, r24 86: 19 f0 breq .+6; 0x8e <main+0x12> 88: 20 93 60 00 sts 0x0060, r18 8c: 02 c0 rjmp .+4; 0x92 <main+0x16> 8e: 90 93 60 00 sts 0x0060, r25 92: 8f 5f subi r24, 0xFF; 255 94: f6 cf rjmp .-20; 0x82 <main+0x6> Берётся тут и подключается в AvrStudio 4.19 без проблем.
Сообщение отредактировал Genadi Zawidowski - Oct 16 2012, 19:41
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|