Перейти к содержанию
    

Глюк оптимизации WinAVR(GCC)

Вот такой код:

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 то код получается нормальный

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Все правильно, оптимизация сработала. В R25 загружается число 5, которое равно количеству сдвигов(загружается в R0: MOV R0, R25) и равно z(запись в память: STS 0x0063, R25).

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Все правильно, оптимизация сработала. В 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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да,сейчас оптимизатор,мягко говоря,не на высоте.

Но в 1 вашем примере я так и не понял,что вам не понравилось?Там вроде все нормально?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Да,сейчас оптимизатор,мягко говоря,не на высоте.

Но в 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 такта

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

котнить сделайте в 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

 

 

===

 

одинаково при оптимизации и по скорости и по размеру кода.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

котнить сделайте в IAR плиз !

 

вот так это делает CVAVR

.............

Так делают все компиляторы

 

SWAP

LSR

ANDI

 

и IAR в том числе

 

а у GCC это именно глюк, который проявляется только если все три константы одинаковые

и если например написать так:

x=5;

z=5;

y>>=5;

то будет все ОК.

 

Самое противное, что между командами из первого поста можно

вставить достаточно много других команд, и если оптимизатору будет хватать

регистров, то он подставит цикл :(

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

На какой версии GCC компилировалось?

 

Вот что делает WinAVR от 22.01.2007 с GCC 4.1.1 (оптимизация - "s"):

 

000000ca <main>:

main():

ca: 95 e0 ldi r25, 0x05 ; 5

cc: 90 93 02 01 sts 0x0102, r25

d0: 80 91 00 01 lds r24, 0x0100

d4: 82 95 swap r24

d6: 86 95 lsr r24

d8: 87 70 andi r24, 0x07 ; 7

da: 80 93 00 01 sts 0x0100, r24

de: 90 93 03 01 sts 0x0103, r25

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

нет тут никакого глюка.

и нет смысла проверять оптимизацию на программках из трех строк.

 

хотите чтобы компилятор делал частные случаи - объявляйте константы должным образом (const x = 5).

 

Не должен компилятор генерить swap если количество сдвигов задано переменной.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

нет тут никакого глюка.

и нет смысла проверять оптимизацию на программках из трех строк.

Глюк есть.

На трех строках никто и не проверял, это выжимка из реального кода в которой проблема осталась.

Не должен компилятор генерить 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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Но от перемены мест слагаемых

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

 

 

это результат с -Os?
Последние 2 листинга с -Os

на -O2 также

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

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

×
×
  • Создать...