|
|
  |
"Оптимизация" в WinAVR и как с этим бороться |
|
|
|
Nov 18 2011, 08:44
|
Местный
  
Группа: Участник
Сообщений: 214
Регистрация: 22-03-10
Из: Саратов
Пользователь №: 56 123

|
Цитата(MaxiMuz @ Nov 18 2011, 12:38)  neiver , _Pasha да действительно, можно и так написать, результат будут тотже что и в моем варианте ! С этим более менее понятно. Неа, результат другой: Код 6c: 86 b3 in r24, 0x16; 22 6e: 8c 70 andi r24, 0x0C; 12 70: 09 f4 brne .+2 ; 0x74 <main+0x8> На ЦЕЛУЮ команду меньше
|
|
|
|
|
Nov 18 2011, 09:00
|

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

|
Цитата(AHTOXA @ Nov 16 2011, 22:58)  Вам же написали, что volatile register писать нельзя. Какие претензии? Это неправильное утверждение! Если из выражения "volatile register int8_t a asm ("r16");" убрать квалификатор volatile, то компилятор воообще обходит использование указанных регистров, используя свои. И хотя код получается короче, неизвестно как дальще поведет себя "оптимизатор" , если программа усложниться ! Цитата(neiver @ Nov 18 2011, 11:44)  Неа, результат другой: Код 6c: 86 b3 in r24, 0x16; 22 6e: 8c 70 andi r24, 0x0C; 12 70: 09 f4 brne .+2 ; 0x74 <main+0x8> На ЦЕЛУЮ команду меньше  На ОДНУ команду не считается  Так исторически сложилось что я проверяю на нулевой рез-т (не нажата не одна кнопка) и зацикливаю в начало
|
|
|
|
|
Nov 18 2011, 10:59
|

Гуру
     
Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954

|
Цитата(MaxiMuz @ Nov 18 2011, 13:00)  На ОДНУ команду не считается Если Вы пытатесь заставить GCC генерить вместо if(!(PINB & KeyMask)) одну команду SBRS (или SBRC), то у Вас ничего не получится. Хотя Atmel и утверждает, что система команд AVR ориентированна на язык Си, то компиляторописатели так не считают... В Вашем первом и втором случаях компилятор действует по шаблону: 1) берёт значение на регистр r24 (то, что Вы расположили некую переменную в регистр - изменит только источник данных: значение будет взято из другого регистра или из ОЗУ): 2) на регистре r24 вычисляет выражение; 3) при необходимости, из регистра r24 сохраняет вычисленное выражение; 4) сравнивает значение выражения (регистр r24) с нулём... Только ну очень хороший оптимизатор заменит эту последовательность одной командой. GCC так сделать не сможет. Для AVR я не знаю компилятора, в который встроен настолько сильный оптимизатор, что сможет повторить Вашу программу на ассемблере. Имхо, если компилятор с ЯВУ генерит код "съедающий" на 10-15% больше ресурсов, чем аналогичная программа на ассемблере, на сегодняшний день - это ОЧЕНЬ хороший компилятор. Заметьте - программа(!!!, причем обычно довольно большая), а не отдельный оператор.
|
|
|
|
|
Nov 18 2011, 11:07
|
Местный
  
Группа: Участник
Сообщений: 214
Регистрация: 22-03-10
Из: Саратов
Пользователь №: 56 123

|
GCC прекрасно может сгенерировать одну команду sbis (или sbiс), но не когда в маске установлены два бита: #define KeyMask ((1<<Btn1)|(1<<Btn2)) Оставим обин бит и будет вам счастье: Код if(!(PINB&KeyMask)) 6c: b2 9b sbis 0x16, 2; 22 А если в маске несколько единичных бит, то только честно сравнивать с нулем.
|
|
|
|
|
Nov 18 2011, 11:54
|

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

|
QUOTE (MaxiMuz @ Nov 18 2011, 12:00)  Это неправильное утверждение! Вдумайтесь, что вы написали. Авторы компилятора указывают, что использовать volatile и register совместно нельзя. Вы обвиняете их во лжи. Достаточно смело, но бесперспективно - во-первых авторы компилятора не читают этот форум, а во-вторых - ну, продолжайте бороться с ветряными мельницами. Напоминает FAQ про яйцо и микроволновку.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Nov 18 2011, 14:36
|
;
     
Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509

|
Цитата(Палыч @ Nov 18 2011, 13:59)  Имхо, если компилятор с ЯВУ генерит код "съедающий" на 10-15% больше ресурсов, чем аналогичная программа на ассемблере, на сегодняшний день - это ОЧЕНЬ хороший компилятор. Заметьте - программа(!!!, причем обычно довольно большая), а не отдельный оператор. ГЦЦ не умеет сливать ПП из разных точек входа в поток с одной командой возврата. Еще - бывают напряги при работе с битовыми полями, сильное юзание регистра Х в адресных выражениях, не использует бит Т и не "подглядывает" за функциями, вызываемыми из прерываний - длинный контекст сохраняется. Больше никаких шероховатостей мною не замечено. А большую программу на асме еще написать надо, чтобы "сделать" современный Си на эти 10-15%.
|
|
|
|
|
Nov 18 2011, 14:45
|
Местный
  
Группа: Участник
Сообщений: 214
Регистрация: 22-03-10
Из: Саратов
Пользователь №: 56 123

|
Цитата(_Pasha @ Nov 18 2011, 18:36)  и не "подглядывает" за функциями, вызываемыми из прерываний - длинный контекст сохраняется. Подглядывает, еще как если функция inline.
|
|
|
|
|
Nov 18 2011, 16:06
|

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

|
Цитата(Палыч @ Nov 18 2011, 13:59)  Если Вы пытатесь заставить GCC генерить вместо if(!(PINB & KeyMask)) одну команду SBRS (или SBRC), то у Вас ничего не получится. ..... с этим место собственно я разобрался. Цитата(_Pasha @ Nov 18 2011, 17:36)  ГЦЦ не умеет сливать ПП из разных точек входа в поток с одной командой возврата. ..... Не понятно о чем вы говорите Цитата(_Pasha @ Nov 18 2011, 17:36)  ...... А большую программу на асме еще написать надо, чтобы "сделать" современный Си на эти 10-15%. большая - маленькая зависит от типа МК. Привожу конкретный пример: Код http://www.radio.ru/archive/2010/07/a19.shtml программка писалась на асме под ATtiny2313, нехватило памяти программ под вторую таблицу мелодий для звонка. Если бы тогда писал на Си то вообще не хватилобы памяти на одну таблицу ! Это при том что я еще проводил оптимизацию программы в ассеблере  Цитата(Палыч @ Nov 18 2011, 14:17)  Да, согласен... Я собирался написать об операторе if ((--Cnt)==0) и команде DEC, но обширное обсуждение в этой теме оператора if(!(PINB & KeyMask)) сбило с мысли... Что хотели написать то ?
|
|
|
|
|
Nov 18 2011, 16:17
|

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

|
Цитата(_Pasha @ Nov 18 2011, 16:36)  ГЦЦ не умеет сливать ПП из разных точек входа в поток с одной командой возврата. Ну, да. Но иногда такие места удаётся оформить в маленькие подпрограмки, которые вызывать в конце (в вумных книгах по программированию давно пишут, что не стоит бояться мелких подпрограмок :-) ). Тогда вкупе с --relax и получается слияние. Цитата(neiver @ Nov 18 2011, 16:45)  Подглядывает, еще как если функция inline. Вот еще до LTO нужно добраться, так там должно за всем подглядывать уметь. Вроде бы к 5-ой аврстудии компилятор идёт уже с LTO. Klen-овые сборки под Linux для ARM дают неплохой эффект. Для AVR у меня не запустились, что-то с библиотеками не срослось. Цитата(MaxiMuz @ Nov 18 2011, 18:06)  Что хотели написать то ? Возможно то, что без зауми с asm("r19") и прочими проявлениями детской болезни левизны dec сам бы появился, и заставлять не пришлось бы (ну тут не dec, но ни по размеру кода, ни по времени выполнения не отличается — возможно, и это сказать хотели): Код #include <avr/io.h> #include <inttypes.h>
#define Btn1 PB2 #define Btn2 PB3
#define KeyMask (1<<Btn1)|(1<<Btn2)
int main (void) { uint8_t Cnt = 0; uint8_t a = 0;
while(1) { if ( !(PINB & (KeyMask)) ) a |= 0x01; if ((--Cnt)==0) { if (a==1 ) { a=0; PINB |= (1 << 2); } } } } Код .global main .type main, @function main: /* prologue: function */ /* frame size = 0 */ ldi r18,lo8(0) .L8: ldi r25,lo8(0) .L7: in r24,54-32 andi r24,lo8(12) brne .L2 ori r25,lo8(1) .L2: subi r18,lo8(-(-1)) brne .L7 cpi r25,lo8(1) brne .L7 sbi 54-32,2 rjmp .L8
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
|
Nov 18 2011, 17:23
|
Местный
  
Группа: Участник
Сообщений: 214
Регистрация: 22-03-10
Из: Саратов
Пользователь №: 56 123

|
Цитата(ReAl @ Nov 18 2011, 20:17)  Вот еще до LTO нужно добраться, так там должно за всем подглядывать уметь. Вроде бы к 5-ой аврстудии компилятор идёт уже с LTO. Klen-овые сборки под Linux для ARM дают неплохой эффект. Для AVR у меня не запустились, что-то с библиотеками не срослось. К сожалению, в avr-gcc LTO не работает. Компилятор к 5-ой аврстудии скомпилирован без поддержки LTO, я пытался скомпилировать avr-gcc сам со включеной LTO - не собрался, видимо чего-то в в AVR бекэнде не хватает.
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|