|
EWARM странные операции со стеком. |
|
|
|
Jun 15 2008, 13:58
|
Местный
  
Группа: Свой
Сообщений: 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  Зачем????. Насколько я понимаю в данной функции все push/pop можно просто выбросить, без ущерба функциональности. Это у меня результат компиляции с максимальной оптимизацией по размеру. Если же оптимизировать по скорости, то меняется только PUSH {R0,LR} на PUSH {R3,LR}. Здесь R3 сохранили, и его же восстановили. Но зачем? Это кривость компилятора? или я чего-то не так делаю? Пугает то, что даже такую простую функцию откомпилить нормально не получается. Это чтож будет на реальных программах. Так недолго довести производительность ARM до уровня AVR  . Как заставить компилятор генерить более оптимальный код? Или переходить на другой компилятор? Переходить не хотелось бы, привык к ИАРу за годы работы с АВР-ками.
|
|
|
|
|
 |
Ответов
|
Jun 15 2008, 18:37
|

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

|
Повторятся трижды было уж слишком  Цитата Но я хочу чтобы этих лишних команд не было! Продолжайте хотеть  . Цитата Согласитесь, в данном конкретном случае их быть не должно, более того, именно ТАКИЕ лишние команды совсем не к лицу хоть сколько-нибудь оптимизирующему компилятору. Ведь они СОВСЕМ ничего не делают! Не пишите такие грандиозные "фунции", ползуйтесь inline. Цитата А вот АБСОЛЮТНО ненужные команды меня просто бесят. Займитесь чем-нибудь другим  , например, выращиванием капусты, говорят успокаивает. Смотрим на аналогичную функцию: Код 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
|
|
|
|
|
Jun 15 2008, 19:35
|
Местный
  
Группа: Свой
Сообщений: 443
Регистрация: 22-07-06
Из: Украина, г. Харьков
Пользователь №: 19 006

|
Цитата(zltigo @ Jun 15 2008, 21:37)  Повторятся трижды было уж слишком  Смотрим на аналогичную функцию: Код 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 не знает еще) кейловский микровижн. Пока с инета (медленно  )качается более новая версия, решил скомпилить под ним. 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 Кажись покороче будет чем даже ваш пример! Так что при нормальном компиляторе "жаловаться на цену" не приходится.
|
|
|
|
|
Jun 15 2008, 19:53
|

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

|
Цитата(Artem_Petrik @ Jun 15 2008, 21:35)  Так что при нормальном компиляторе "жаловаться на цену" не приходится. Только не увлекайтесь выбором компиляторов по отдельным тестовым примерам и уж тем более состоящих из нескольких строк. Цитата Надо отметить, что ваш пример выглядит красиво. А под какой это проц? LPC2xxx. Хидеры обычно пишу/дописываю свои, дабы иметь переносимые не зависеть от компилятора. Atmel-овский стиль, конечно максимально дебильный из всех возможных
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
Сообщений в этой теме
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
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|