|
|
  |
Глюк оптимизации WinAVR(GCC), сдвиги << и >> |
|
|
|
Jan 28 2007, 05:05
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Вот такой код: Код unsigned char x,y=0x34,z;
int main() { x=5; y=y>>5; z=5; return 0; } А это "оптимизированный" выход, опции -O2 или -O1 Код 7: x=5; +00000032: E095 LDI R25,0x05 Load immediate +00000033: 93900062 STS 0x0062,R25 Store direct to data space 8: y=y>>5; +00000035: 91800060 LDS R24,0x0060 Load direct from data space +00000037: 2E09 MOV R0,R25 Copy register +00000038: C001 RJMP PC+0x0002 Relative jump +00000039: 9586 LSR R24 Logical shift right +0000003A: 940A DEC R0 Decrement +0000003B: F7EA BRPL PC-0x02 Branch if plus +0000003C: 93800060 STS 0x0060,R24 Store direct to data space 9: z=5; +0000003E: 93900063 STS 0x0063,R25 Store direct to data space Смотрим на цикл и тихо радуемся Если x!=z то код получается нормальный
|
|
|
|
|
Jan 28 2007, 11:37
|
Участник

Группа: Новичок
Сообщений: 73
Регистрация: 10-01-07
Пользователь №: 24 292

|
вроде верно все - 5 раз сдвигает в право.
|
|
|
|
|
Jan 28 2007, 13:32
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(pulsar-17 @ Jan 28 2007, 11:37)  Все правильно, оптимизация сработала. В R25 загружается число 5, которое равно количеству сдвигов(загружается в R0: MOV R0, R25) и равно z(запись в память: STS 0x0063, R25). Ну если это оптимизация  Если поменять z Код x=5; y=y>>5; z=6; то получим Код 7: x=5; +00000032: E085 LDI R24,0x05 Load immediate +00000033: 93800062 STS 0x0062,R24 Store direct to data space 8: y=y>>5; +00000035: 91800060 LDS R24,0x0060 Load direct from data space +00000037: 9582 SWAP R24 Swap nibbles +00000038: 9586 LSR R24 Logical shift right +00000039: 7087 ANDI R24,0x07 Logical AND with immediate +0000003A: 93800060 STS 0x0060,R24 Store direct to data space 9: z=6; +0000003C: E086 LDI R24,0x06 Load immediate +0000003D: 93800063 STS 0x0063,R24 Store direct to data space 1 Почуствуйте разницу А особенно весело выглядит вот это: Код x=1; y=y>>1; z=1;
7: x=1; +00000032: E091 LDI R25,0x01 Load immediate +00000033: 93900062 STS 0x0062,R25 Store direct to data space 8: y=y>>1; +00000035: 91800060 LDS R24,0x0060 Load direct from data space +00000037: 2E09 MOV R0,R25 Copy register +00000038: C001 RJMP PC+0x0002 Relative jump +00000039: 9586 LSR R24 Logical shift right +0000003A: 940A DEC R0 Decrement +0000003B: F7EA BRPL PC-0x02 Branch if plus +0000003C: 93800060 STS 0x0060,R24 Store direct to data space 9: z=1; +0000003E: 93900063 STS 0x0063,R25 Store direct to data space 1 вместо Код +00000035: 91800060 LDS R24,0x0060 Load direct from data space +000000xx: 9586 LSR R24 Logical shift right +000000xx: 93800060 STS 0x0060,R24 Store direct to data space
|
|
|
|
|
Jan 28 2007, 16:06
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(WHALE @ Jan 28 2007, 15:45)  Да,сейчас оптимизатор,мягко говоря,не на высоте. Но в 1 вашем примере я так и не понял,что вам не понравилось?Там вроде все нормально? Ну, вот это: Код +00000037: 2E09 MOV R0,R25 Copy register +00000038: C001 RJMP PC+0x0002 Relative jump +00000039: 9586 LSR R24 Logical shift right +0000003A: 940A DEC R0 Decrement +0000003B: F7EA BRPL PC-0x02 Branch if plus 10 байт - 25 тактов вместо вот этого: Код +00000037: 9582 SWAP R24 Swap nibbles +00000038: 9586 LSR R24 Logical shift right +00000039: 7087 ANDI R24,0x07 Logical AND with immediate 6 байт - 3 такта
|
|
|
|
|
Jan 28 2007, 16:18
|
Участник

Группа: Новичок
Сообщений: 73
Регистрация: 10-01-07
Пользователь №: 24 292

|
котнить сделайте в IAR плиз !
вот так это делает CVAVR
;x=5; LDI R30,LOW(5) MOV R4,R30 ;y=y>>5; MOV R30,R5 SWAP R30 ANDI R30,0xF LSR R30 MOV R5,R30 ;z=5; LDI R30,LOW(5) MOV R6,R30
===
одинаково при оптимизации и по скорости и по размеру кода.
|
|
|
|
|
Jan 28 2007, 16:38
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(Abakt @ Jan 28 2007, 16:18)  котнить сделайте в IAR плиз !
вот так это делает CVAVR ............. Так делают все компиляторы SWAP LSR ANDI и IAR в том числе а у GCC это именно глюк, который проявляется только если все три константы одинаковые и если например написать так: x=5; z=5; y>>=5; то будет все ОК. Самое противное, что между командами из первого поста можно вставить достаточно много других команд, и если оптимизатору будет хватать регистров, то он подставит цикл
|
|
|
|
|
Apr 3 2008, 11:32
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(defunct @ Apr 3 2008, 14:14)  нет тут никакого глюка. и нет смысла проверять оптимизацию на программках из трех строк. Глюк есть. На трех строках никто и не проверял, это выжимка из реального кода в которой проблема осталась. Цитата Не должен компилятор генерить swap если количество сдвигов задано переменной. да не задано оно переменной, сдвиг на 5 разрядов к переменной x не имеет никакого отношения Было что-то типа такого: Код #include <avr\io.h>
unsigned char y=0x34;
int main() {
ADMUX = (1<<MUX2)|(1<<MUX0); ............................ y = y >> 5; ............................ TCNT0 = 5; ........................... while (1); } С вот таким результатом компиляции: Код 8: ADMUX = (1<<MUX2)|(1<<MUX0); +00000032: E095 LDI R25,0x05 Load immediate +00000033: B997 OUT 0x07,R25 Out to I/O location 10: y = y >> 5; +00000034: 91800060 LDS R24,0x0060 Load direct from data space +00000036: 2E09 MOV R0,R25 Copy register +00000037: C001 RJMP PC+0x0002 Relative jump +00000038: 9586 LSR R24 Logical shift right +00000039: 940A DEC R0 Decrement +0000003A: F7EA BRPL PC-0x02 Branch if plus +0000003B: 93800060 STS 0x0060,R24 Store direct to data space 12: TCNT0 = 5; +0000003D: BF92 OUT 0x32,R25 Out to I/O location
|
|
|
|
|
Apr 3 2008, 11:49
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Но от перемены мест слагаемых Код int main() {
y = y >> 5;
ADMUX = (1<<MUX2)|(1<<MUX0);
TCNT0 = 5;
while (1); } все конечно меняется: Код 8: y = y >> 5; +00000032: 91800060 LDS R24,0x0060 Load direct from data space +00000034: 9582 SWAP R24 Swap nibbles +00000035: 9586 LSR R24 Logical shift right +00000036: 7087 ANDI R24,0x07 Logical AND with immediate +00000037: 93800060 STS 0x0060,R24 Store direct to data space 10: ADMUX = (1<<MUX2)|(1<<MUX0); +00000039: E085 LDI R24,0x05 Load immediate +0000003A: B987 OUT 0x07,R24 Out to I/O location 12: TCNT0 = 5; +0000003B: BF82 OUT 0x32,R24 Out to I/O location Цитата(defunct @ Apr 3 2008, 15:47)  это результат с -Os? Последние 2 листинга с -Os на -O2 также
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|