реклама на сайте
подробности

 
 
> EWARM странные операции со стеком.
Artem_Petrik
сообщение Jun 15 2008, 13:58
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 443
Регистрация: 22-07-06
Из: Украина, г. Харьков
Пользователь №: 19 006



Вот и у меня на горизонте замаячил проектик, который видимо желательно реализовывать на MCU семейства ARM. Так что я приступил к их освоению.
Имею (вредную?) привычку после компиляции смотреть листинг, чтобы оценить насколько результат близок к тому, что я написал бы на ассемблере. И, как всегда, смотрю, и сердце кровью обливается. Это даже при том, что я в армовском ассемблере почти ничего не понимаю. Поначалу у меня была сравнительно старая версия иара - 4.40A, и я решил что неоптимальность связанна именно с этим. Поэтому скачал 5.11. Код действительно стал лучше, но не на много. Наиболее непонятны для меня некоторые операции со стеком, которые компилятор вставляет при входе/выходе из процедуры при компиляции в режиме THUMB. Вот достаточно простой пример:
Код
      3          void putchar( char a)
      4          {
   \                     putchar:
   \   00000000   01B5               PUSH     {R0,LR}
      5            AT91PS_USART pUSART = AT91C_BASE_US0;
      6            
      7            while( !(pUSART->US_CSR & AT91C_US_TXRDY) );
   \                     ??putchar_0:
   \   00000002   0449               LDR      R1,??putchar_1  ;; 0xfffc0014
   \   00000004   0968               LDR      R1,[R1, #+0]
   \   00000006   8907               LSLS     R1,R1,#+30
   \   00000008   FBD5               BPL      ??putchar_0
      8            pUSART->US_THR = a;
   \   0000000A   0249               LDR      R1,??putchar_1  ;; 0xfffc0014
   \   0000000C   8860               STR      R0,[R1, #+8]
      9          }
   \   0000000E   08BC               POP      {R3}
   \   00000010   01BC               POP      {R0}
   \   00000012   0047               BX       R0              ;; return
   \                     ??putchar_1:
   \   00000014   1400FCFF           DC32     0xfffc0014

Несмотря на то, что в функции не происходит вызова других функций, зачем-то в стек сохраняется LR. Более того, с ним за компанию сохраняется параметр, передаваемый в функцию, который потом восстанавливается в r3 07.gif Зачем????. Насколько я понимаю в данной функции все push/pop можно просто выбросить, без ущерба функциональности. Это у меня результат компиляции с максимальной оптимизацией по размеру. Если же оптимизировать по скорости, то меняется только PUSH {R0,LR} на PUSH {R3,LR}. Здесь R3 сохранили, и его же восстановили. Но зачем?
Это кривость компилятора? или я чего-то не так делаю? Пугает то, что даже такую простую функцию откомпилить нормально не получается. Это чтож будет на реальных программах. Так недолго довести производительность ARM до уровня AVR 05.gif . Как заставить компилятор генерить более оптимальный код? Или переходить на другой компилятор? Переходить не хотелось бы, привык к ИАРу за годы работы с АВР-ками.
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
zltigo
сообщение Jun 15 2008, 18:37
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Повторятся трижды было уж слишком smile.gif
Цитата
Но я хочу чтобы этих лишних команд не было!

Продолжайте хотеть smile.gif.
Цитата
Согласитесь, в данном конкретном случае их быть не должно, более того, именно ТАКИЕ лишние команды совсем не к лицу хоть сколько-нибудь оптимизирующему компилятору. Ведь они СОВСЕМ ничего не делают!

Не пишите такие грандиозные "фунции", ползуйтесь inline.
Цитата
А вот АБСОЛЮТНО ненужные команды меня просто бесят.

Займитесь чем-нибудь другим smile.gif, например, выращиванием капусты, говорят успокаивает.
Смотрим на аналогичную функцию:
Код
     43          void testputchar( char ch )
     44          {
     45              while( !(U0LSR & LSR_TEMT) );
   \                     testputchar:
   \                     ??testputchar_0:
   \   00000000   E014A0E3           MOV      R1,#-536870912
   \   00000004   C01C81E3           ORR      R1,R1,#0xC000
   \   00000008   1420D1E5           LDRB     R2,[R1, #+20]
   \   0000000C   400012E3           TST      R2,#0x40
   \   00000010   FAFFFF0A           BEQ      ??testputchar_0
     46              U0THR = ch;
   \   00000014   0000C1E5           STRB     R0,[R1, #+0]
     47          }
   \   00000018   0EF0A0E1           MOV      PC,LR         ;; return


Цитата
Так что экономия выходит не любой ценой, а "нахаляву".

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


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Artem_Petrik
сообщение Jun 15 2008, 19:35
Сообщение #3


Местный
***

Группа: Свой
Сообщений: 443
Регистрация: 22-07-06
Из: Украина, г. Харьков
Пользователь №: 19 006



Цитата(zltigo @ Jun 15 2008, 21:37) *
Повторятся трижды было уж слишком smile.gif
Смотрим на аналогичную функцию:
Код
     43          void testputchar( char ch )
     44          {
     45              while( !(U0LSR & LSR_TEMT) );
   \                     testputchar:
   \                     ??testputchar_0:
   \   00000000   E014A0E3           MOV      R1,#-536870912
   \   00000004   C01C81E3           ORR      R1,R1,#0xC000
   \   00000008   1420D1E5           LDRB     R2,[R1, #+20]
   \   0000000C   400012E3           TST      R2,#0x40
   \   00000010   FAFFFF0A           BEQ      ??testputchar_0
     46              U0THR = ch;
   \   00000014   0000C1E5           STRB     R0,[R1, #+0]
     47          }
   \   00000018   0EF0A0E1           MOV      PC,LR          ;; return


Пардон, что то сегодня у меня инет жутко глючит. Пол часа ответ посылал. Кликаю отправить - думает пару минут, и выдает ошибку. Оказывается три раза все же прошло.
Надо отметить, что ваш пример выглядит красиво. А под какой это проц? Дело в том, что я обратил внимание на то, что атмеловские инклуды с описанием периферии радикально отличаются от инклудов других производителей. И пока у меня была версия 4.40А именно с этим были связаны многие проколы в оптимизации. Так при записи в регистры одной и той же периферии, вместо адресации со смещением компилятор грузил адрес LDR-ом каждый раз. Впрочем, вроде в версии 5.11 это прошло. Но может не совсем?
Кстати, нашол у себя древний (даже про SAM7X не знает еще) кейловский микровижн. Пока с инета (медленно sad.gif )качается более новая версия, решил скомпилить под ним. CARM тоже генерит чертий-что, а вот real view выдал такое
Код
                          THUMB
                  putchar PROC
;;;4      void putchar( char a)
;;;5      {
000000  4902              LDR      r1,|L2.12|
;;;6        AT91PS_USART pUSART = AT91C_BASE_US0;
;;;7        
;;;8        while( !(pUSART->US_CSR & AT91C_US_TXRDY) );
                  |L2.2|
000002  694a              LDR      r2,[r1,#0x14]
000004  0792              LSLS     r2,r2,#30
000006  d5fc              BPL      |L2.2|
;;;9        pUSART->US_THR = a;
000008  61c8              STR      r0,[r1,#0x1c]
;;;10     }
00000a  4770              BX       lr
                  |L2.12|
00000c  fffc0000          DCD      0xfffc0000
                          ENDP


Кажись покороче будет чем даже ваш пример! Так что при нормальном компиляторе "жаловаться на цену" не приходится.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jun 15 2008, 19:53
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



Цитата(Artem_Petrik @ Jun 15 2008, 21:35) *
Так что при нормальном компиляторе "жаловаться на цену" не приходится.

Только не увлекайтесь выбором компиляторов по отдельным тестовым примерам и уж тем более состоящих из нескольких строк.
Цитата
Надо отметить, что ваш пример выглядит красиво. А под какой это проц?

LPC2xxx. Хидеры обычно пишу/дописываю свои, дабы иметь переносимые не зависеть от компилятора.
Atmel-овский стиль, конечно максимально дебильный из всех возможных sad.gif


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- Artem_Petrik   EWARM странные операции со стеком.   Jun 15 2008, 13:58
- - zltigo   Цитата(Artem_Petrik @ Jun 15 2008, 15:58)...   Jun 15 2008, 16:16
- - Artem_Petrik   Цитата(zltigo @ Jun 15 2008, 19:16) Вот и...   Jun 15 2008, 18:26
|- - Artem_Petrik   Цитата(zltigo @ Jun 15 2008, 22:53) Тольк...   Jun 15 2008, 20:28
|- - zltigo   Цитата(Artem_Petrik @ Jun 15 2008, 22:28)...   Jun 15 2008, 20:41
|- - aaarrr   Цитата(Artem_Petrik @ Jun 16 2008, 00:28)...   Jun 15 2008, 20:43
- - GetSmart   Цитата(zltigo)Смотрим на аналогичную функцию:... в...   Jun 15 2008, 18:51
|- - zltigo   Цитата(GetSmart @ Jun 15 2008, 20:51) ......   Jun 15 2008, 18:58
- - GetSmart   Цитата(zltigo)Thumb:Ну, это другое дело А кто-нит...   Jun 15 2008, 19:50
- - Artem_Petrik   Стоп! Что-то у меня лыжи не едут! Откомпил...   Jun 15 2008, 20:49
|- - zltigo   Цитата(Artem_Petrik @ Jun 15 2008, 22:49)...   Jun 15 2008, 21:11
|- - Artem_Petrik   Цитата(zltigo @ Jun 16 2008, 00:11) По на...   Jun 15 2008, 21:27
|- - zltigo   Цитата(Artem_Petrik @ Jun 15 2008, 23:27)...   Jun 15 2008, 21:57
- - aaarrr   Оптимизация-то включена вообще?   Jun 15 2008, 20:51
- - Artem_Petrik   Цитата(aaarrr @ Jun 15 2008, 23:51) Оптим...   Jun 15 2008, 20:56


Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 23rd July 2025 - 10:56
Рейтинг@Mail.ru


Страница сгенерированна за 0.0142 секунд с 7
ELECTRONIX ©2004-2016