|
Эффективность кода WinAVR |
|
|
|
Apr 21 2008, 07:12
|

Профессионал
    
Группа: Участник
Сообщений: 1 091
Регистрация: 25-07-07
Из: Саратов
Пользователь №: 29 357

|
Цитата(Kuzmi4 @ Apr 21 2008, 11:07)  2 777777 - какие ключи использовали ?? То, что AVR поставил по умолчанию: -Wall -gdwarf-2 -O0 Кстати, на означает ли последний ключ отключение оптимизации? Где бы про них почитать, а то хелп только на AVR Studio, а на сишный компилятор нигде не найду
|
|
|
|
|
Apr 21 2008, 09:03
|

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

|
Цитата(777777 @ Apr 21 2008, 11:54)  Э, это не то! там они просто дефайнятся, а я хотел поддержки со стороны компилятора, причем чтобы bool имел размер в 1 бит, как в 51 (правда, там этот тип называется bit). И если объявить такую функцию, то она будет возвращать свое значениев не в регистре, а в бите переноса. И, зачем это Вам? AVR - это не МК51, битовоадресуемой памяти нет, битовых операций тоже ( SBI, CBI, BST, BLD - невсчет).
|
|
|
|
|
Apr 21 2008, 09:24
|
Знающий
   
Группа: Свой
Сообщений: 709
Регистрация: 3-05-05
Пользователь №: 4 693

|
Цитата(Палыч @ Apr 21 2008, 13:03)  И, зачем это Вам? AVR - это не МК51, битовоадресуемой памяти нет, битовых операций тоже ( SBI, CBI, BST, BLD - невсчет). Есть, есть...;О) Мало, не везде, но есть. GPIOR0...2
|
|
|
|
|
Apr 21 2008, 09:48
|

Участник

Группа: Новичок
Сообщений: 19
Регистрация: 14-04-08
Из: Москва
Пользователь №: 36 755

|
Цитата(Палыч @ Apr 21 2008, 11:18)  -O0 - Do not optimize
Ключи описаны в файле gcc.pdf А где его найти ? У меня в инсталяции WinAVR только 6 .pdf файлов и среди них нету - gcc.pdf
|
|
|
|
|
Apr 21 2008, 14:43
|

Профессионал
    
Группа: Участник
Сообщений: 1 091
Регистрация: 25-07-07
Из: Саратов
Пользователь №: 29 357

|
Я в шоке. Какой код можно сгенерировать на такую строку: Код if(v & F0BIT) Вот результат: Код if(v & F0BIT) +0000003B: 2F24 MOV R18,R20 Copy register +0000003C: 2733 CLR R19 Clear Register +0000003D: 2F93 MOV R25,R19 Copy register +0000003E: 2F82 MOV R24,R18 Copy register +0000003F: E063 LDI R22,0x03 Load immediate +00000040: 9596 LSR R25 Logical shift right +00000041: 9587 ROR R24 Rotate right through carry +00000042: 956A DEC R22 Decrement +00000043: F7E1 BRNE PC-0x03 Branch if not equal +00000044: 7081 ANDI R24,0x01 Logical AND with immediate +00000045: 7090 ANDI R25,0x00 Logical AND with immediate +00000046: 2388 TST R24 Test for Zero or Minus +00000047: F011 BREQ PC+0x03 Branch if equal А все потому, что константа F0BIT описана следующим образом: Код const int F0BIT = (1<<F0); const int F1BIT = (1<<F1); И вот вместо того, чтобы на этапе компиляции вычислить это выражение и сделать логическое И с переменной, компилятор решает сдвинуть переменную на F0 битов! Особенно порадовала строка ANDI R25,0x00. Впрочем, CLR R19 с последующей MOV R25,R19 тоже ничего... А я уж было обрадовался что компилятор заработал...
|
|
|
|
|
Apr 21 2008, 15:46
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(777777 @ Apr 21 2008, 19:42)  Тот же результат наблюдается если написать const int F0BIT = 8; И ничего затейливого в этом нет. Пользуйтесь define и проблем не будет: Код #define FOBIT 8 #define FOBIT_MASK (1<<FOBIT) ......
if (XXX & FOBIT_MASK) ............
|
|
|
|
|
Apr 21 2008, 16:44
|

Профессионал
    
Группа: Участник
Сообщений: 1 091
Регистрация: 25-07-07
Из: Саратов
Пользователь №: 29 357

|
Цитата(Палыч @ Apr 21 2008, 19:48)  Что, тоже сдвигает?  А, если так: #define F0BIT (1<<F0) То же самое. Впрочем, я уже скачал новую версию, 20080411 (4.3.0), там это место генерируется весьма эффективно, через SBRS, но там в другом месте глюк - часть кода не транслируется вообще, завтра буду разбираться.
|
|
|
|
|
Apr 21 2008, 17:11
|
Местный
  
Группа: Свой
Сообщений: 408
Регистрация: 21-10-06
Из: Санкт-Петербург
Пользователь №: 21 527

|
GCC 3.4.6 Код #define F0 5 const int F0BIT = (1<<F0); uint16_t v;
int main(void) { if(v & F0BIT) PORTD = 0; else PORTD = 0xFF;
while(1){}; } Код ---- main.c --------------------------------------------------------------------------------------- 23: if(v & F0BIT) PORTD = 0; else PORTD = 0xFF; +00000032: 91800062 LDS R24,0x0062 Load direct from data space +00000034: 91900063 LDS R25,0x0063 Load direct from data space +00000036: FF85 SBRS R24,5 Skip if bit in register set +00000037: C002 RJMP PC+0x0003 Relative jump +00000038: BA12 OUT 0x12,R1 Out to I/O location +00000039: C002 RJMP PC+0x0003 Relative jump +0000003A: EF8F SER R24 Set Register +0000003B: BB82 OUT 0x12,R24 Out to I/O location 33: while(1){}; +0000003C: CFFF RJMP PC-0x0000 Relative jump Никто ничего не вычисляет
|
|
|
|
|
Apr 21 2008, 17:50
|
Местный
  
Группа: Свой
Сообщений: 408
Регистрация: 21-10-06
Из: Санкт-Петербург
Пользователь №: 21 527

|
Цитата(Aesthete Animus @ Apr 21 2008, 21:36)  Вопрос конечно совсем не в тему... Но не скажите как вы генерите листинги, что в них вставляются комментарии (Load direct from data space, Out to I/O location и пр.)? Я запускаю отладку в студии, а потом view -> dissasembler -> ctrl+c -> ctrl+v...
|
|
|
|
|
Apr 22 2008, 04:31
|

Профессионал
    
Группа: Участник
Сообщений: 1 091
Регистрация: 25-07-07
Из: Саратов
Пользователь №: 29 357

|
Цитата(Qwertty @ Apr 21 2008, 21:11)  GCC 3.4.6 У меня была 3.4.5 Цитата(777777 @ Apr 21 2008, 20:44)  ... Впрочем, я уже скачал новую версию, 20080411 (4.3.0), там это место генерируется весьма эффективно, через SBRS, но там в другом месте глюк - часть кода не транслируется вообще, завтра буду разбираться. После уменьшения кода до минимально необходимого для повторения глюка, удалось понять его причину. Дело в том, что gcc - компилятор "настоящий" (в отличие от Keil, напимер), поэтому volatile нужно писать всегда, где это надо
|
|
|
|
|
Apr 22 2008, 07:05
|
Местный
  
Группа: Свой
Сообщений: 408
Регистрация: 21-10-06
Из: Санкт-Петербург
Пользователь №: 21 527

|
Цитата(777777 @ Apr 22 2008, 08:31)  У меня была 3.4.5 Попробовал в 4.2.2 - тоже нормально, почти оптимальный результат. Цитата(777777 @ Apr 22 2008, 08:31)  После уменьшения кода до минимально необходимого для повторения глюка, удалось понять его причину. Дело в том, что gcc - компилятор "настоящий" (в отличие от Keil, напимер), поэтому volatile нужно писать всегда, где это надо  Никогда не видел, что бы отсутствие волатила препятствовало компиляции. Обычно это совсем не мешает, просто программа работает не совсем так, как надо. Или совсем не так  Можно примерчик кода не собирающегося без волатила?
|
|
|
|
|
Apr 22 2008, 07:30
|

Профессионал
    
Группа: Участник
Сообщений: 1 091
Регистрация: 25-07-07
Из: Саратов
Пользователь №: 29 357

|
Цитата(Qwertty @ Apr 22 2008, 11:05)  Никогда не видел, что бы отсутствие волатила препятствовало компиляции. Обычно это совсем не мешает, просто программа работает не совсем так, как надо. Или совсем не так  Ну так программа работает не так именно потому, что компилятор постарался  Цитата(Qwertty @ Apr 22 2008, 11:05)  Можно примерчик кода не собирающегося без волатила? Код #include <avr/io.h>
#define CTRL0 0 // output bits #define CTRL1 1 //
#define F0 2 // input bits #define F1 3 //
/*volatile*/ int8_t Pulse;
int main() { // port B PORTB = 0xff; DDRB = (1<<CTRL0)|(1<<CTRL1);
uint8_t State = PINB; // previous B state Pulse = 0;
while(1) { // inc/dec Pulse if F1 changes if((PINB^State) & (1<<F1)) { State = PINB; // *** uint8_t v = -1; if(State & (1<<F0)) v = 1; if(State & (1<<F1)) v = -v; Pulse += v; } } } переменную Pulse предполагается использовать в прерывании. Но компилятор об этом не знает и потому считает ненужными все стоки после // *** так как он не видт использования Pulse. Правда, тогда непонятно почему он вообще не выкидывает while(1), ведь внутри него ничего не происходит - порты не записываются, а локальные переменные не должны никого интересовать.
Сообщение отредактировал 777777 - Apr 22 2008, 07:37
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|