|
вопрос по IARy, IAR спасовал? |
|
|
|
Jun 16 2005, 09:30
|

Участник

Группа: Новичок
Сообщений: 47
Регистрация: 5-03-05
Пользователь №: 3 082

|
Компилю текст: #pragma vector = TIMER2_OVF_vect __interrupt void system_timer() { blink_timer++; }
и выдает:
#pragma vector = TIMER2_OVF_vect __interrupt void system_timer() ST -Y, R31 ST -Y, R30 ST -Y, R17 ST -Y, R16 IN R17, 0x3F } blink_timer++; LDI R30, LOW(blink_timer) LDI R31, (blink_timer) >> 8 LD R16, Z INC R16 ST Z, R16 } OUT 0x3F, R17 LD R16, Y+ LD R17, Y+ LD R30, Y+ LD R31, Y+ RETI
при максимальной оптимизации. Не пойму почему бы ему не использовать STS? или я что-то не так пишу или хваленый иар не спосбен на подвиги? ЧТО Я НЕ ТАК ДЕЛАЮ?
|
|
|
|
|
 |
Ответов
|
Jun 21 2005, 06:35
|

Adept
     
Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343

|
Цитата(AlexOr @ Jun 20 2005, 19:41) Кстати, LDI R30, LOW(blink_timer) LDI R31, (blink_timer) >> 8 LD R16, Z INC R16 ST Z, R16
занимает столько же места как и
LDS R30,_blink_timer SUBI R30,-LOW(1) STS _blink_timer,R30
но последнее в прерывании намного выгоднее (быстрее и менее расходно по регистрам). Это до тех пор, пока у Вас единственное обращение к однобайтовой переменной. Сделайте эту переменную интом, выигрыш не замедлит проявиться. Или, к примеру, если там не к одной переменной обращение, а к нескольким, лежащим в пределах досягаемости указателя (для этого их надо объявлять вместе). Или к структуре обращение. Словом, когда ситуация уходить от первого простейшего случая, результат меняется Цитата(AlexOr @ Jun 20 2005, 19:41) Черт меня дернул сделать проект на IAR. Сейчас взглянул на прологи/эпилоги и Ужаснулся. Не стОит так переживать из-за этой мелочи. Она погоду не делает совершенно. Наоборот, способность IAR'а приводить обращения к косвенным дает очень приличный выигрыш на деле. AVR-GCC имеет весьма неплохой кодогенератор, но он проигрывает IAR'у именно на этом моменте - AVR-GCC злоупотребляет lds/sts, из-за чего размер кода там получается больше. Не знаю, как сегодня обстоит дело, но некоторое время назад остальные компляторы - CodeVision, ImageCraft уступали по качеству кодогенерации обоим - и IAR'у, и AVR-GCC. Может сейчас что-то изменилось, но сомневаюсь. Сравнивать надо не на коде из трех строк, а на реальных проектах. Попробуйте, увидите, что IAR рулит.
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
|
Jun 21 2005, 07:08
|

Участник

Группа: Новичок
Сообщений: 47
Регистрация: 5-03-05
Пользователь №: 3 082

|
[/quote] Не стОит так переживать из-за этой мелочи. Она погоду не делает совершенно. Наоборот, способность IAR'а приводить обращения к косвенным дает очень приличный выигрыш на деле. AVR-GCC имеет весьма неплохой кодогенератор, но он проигрывает IAR'у именно на этом моменте - AVR-GCC злоупотребляет lds/sts, из-за чего размер кода там получается больше. [/quote] Но прерывание ИАР слишком раздул, а надо то тока инкрементировать глобальную переменную. кстати это системный таймер и я думаю, что там не одна переменная может быть, но и несколько, а если они не подряд - то работа с указателями это только проигрыш.
|
|
|
|
|
Jun 21 2005, 07:36
|

Adept
     
Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343

|
Цитата(LeoLabs @ Jun 21 2005, 13:08) Но прерывание ИАР слишком раздул, а надо то тока инкрементировать глобальную переменную. кстати это системный таймер и я думаю, что там не одна переменная может быть, но и несколько, а если они не подряд - то работа с указателями это только проигрыш. Ну и сколько это байт оверхеда на фоне всего проекта? Сравнивайте весь проект (или хотя бы более-менее значимую часть), скомпиленные одним компиятором и другим. Переменным не обязательно быть подряд. Им достаточно быть в пределах досягаемости указателя - 64 байта. Для того, чтобы они были вместе, достаточно их объявить вместе и включить оптимизацию clustering variables, которая, afair, включена по умолчанию.
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
|
Jun 21 2005, 07:57
|

Участник

Группа: Новичок
Сообщений: 47
Регистрация: 5-03-05
Пользователь №: 3 082

|
Цитата(dxp @ Jun 21 2005, 14:36) Цитата(LeoLabs @ Jun 21 2005, 13:08) Но прерывание ИАР слишком раздул, а надо то тока инкрементировать глобальную переменную. кстати это системный таймер и я думаю, что там не одна переменная может быть, но и несколько, а если они не подряд - то работа с указателями это только проигрыш. Ну и сколько это байт оверхеда на фоне всего проекта? Сравнивайте весь проект (или хотя бы более-менее значимую часть), скомпиленные одним компиятором и другим. Переменным не обязательно быть подряд. Им достаточно быть в пределах досягаемости указателя - 64 байта. Для того, чтобы они были вместе, достаточно их объявить вместе и включить оптимизацию clustering variables, которая, afair, включена по умолчанию. ну что ж: вот расстояние между байтами 19, а как обрабатывается - при полной оптимизации, включая Clustering of variables. 5 #pragma vector = TIMER2_OVF_vect \ In segment CODE, align 2, keep-with-next 6 __interrupt void system_timer(void) \ system_timer: 7 { \ 00000000 93FA ST -Y, R31 \ 00000002 93EA ST -Y, R30 \ 00000004 931A ST -Y, R17 \ 00000006 930A ST -Y, R16 \ 00000008 B71F IN R17, 0x3F 8 blink_timer++; \ 0000000A .... LDI R30, 0x66 \ 0000000C .... LDI R31, 0x01 \ 0000000E 8100 LD R16, Z \ 00000010 9503 INC R16 \ 00000012 8300 ST Z, R16 9 mySREG++; \ 00000014 .... LDI R30, 0x79 \ 00000016 .... LDI R31, 0x01 \ 00000018 8100 LD R16, Z \ 0000001A 9503 INC R16 \ 0000001C 8300 ST Z, R16 10 } \ 0000001E BF1F OUT 0x3F, R17 \ 00000020 9109 LD R16, Y+ \ 00000022 9119 LD R17, Y+ \ 00000024 91E9 LD R30, Y+ \ 00000026 91F9 LD R31, Y+ \ 00000028 9518 RETI В чем дело то? может у меня завихрения? да и в прерываниях, которые очень критичны к скорости, совсем ни к чему указатели. а по поводу памяти - то ее почти всегда хватит, напротив быстродействия всегда мало.
|
|
|
|
|
Jun 21 2005, 09:05
|

Adept
     
Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343

|
Цитата(LeoLabs @ Jun 21 2005, 13:57) ну что ж: вот расстояние между байтами 19, а как обрабатывается - при полной оптимизации, включая Clustering of variables. Непонятно, как Вы объявили переменные. Нужно, чтобы они были вместе объявлены, чтобы компилятор видел их одновременно. Если они в разных файлах объявлены, то, ессно, компилятор тут ничего поделать не сможет (даже если они реально попали в предел 64 байта один от другого), т.к. просто не знает, что они рядом и не может рулить их размещением. А вот как это получается: Код char blink_timer1; char buf[200]; char blink_timer2;
#pragma vector = TIMER2_OVF_vect __interrupt void system_timer() { blink_timer1++; blink_timer2++; }
результат: __interrupt void system_timer() ??system_timer: { 93FA ST -Y, R31 93EA ST -Y, R30 931A ST -Y, R17 930A ST -Y, R16 B71F IN R17, 0x3F blink_timer1++; .... LDI R30, LOW(blink_timer1) .... LDI R31, (blink_timer1) >> 8 8100 LD R16, Z 9503 INC R16 8300 ST Z, R16 blink_timer2++; 8101 LDD R16, Z+1 9503 INC R16 8301 STD Z+1, R16 } BF1F OUT 0x3F, R17 9109 LD R16, Y+ 9119 LD R17, Y+ 91E9 LD R30, Y+ 91F9 LD R31, Y+ 9518 RETI Заметьте, что смещение при обращении ко второй переменной равно 1, несмотря на то, что при объявлении между ними массив в 200 байт. Т.е. компилятор эффективно расположил обе переменные последовательно - имеет право. Это и есть clustering variables. Т.е. достаточно, чтобы оба объявления были доступны компилятору в одной единице компиляции. Цитата(LeoLabs @ Jun 21 2005, 13:57) да и в прерываниях, которые очень критичны к скорости, совсем ни к чему указатели. а по поводу памяти - то ее почти всегда хватит, напротив быстродействия всегда мало. Если Вам мало быстродействия, при этом у Вас просто инкремент байта - напишите это на асме и не страдайте. Я не спорю с тем, что в данном конкретном случае IAR делает не лучшим образом - злоупотреляет переходами к косвенным обращениям, - но поверьте, в целом зачастую именно это дает ему значимое преимущество. Об этом их backfire следует сообщить разработчикам, чтобы они в дальнейшем поработали над поведением компилятора в ISR. Хотя, думается, что если до сих пор не исправили, то это по той причине, что никого [из пользователей] этот факт особенно не волнует. Ведь и в самом деле, если работоспособность и устойчивость системы зависит от пары тактов, то тут явно что-то не то в дизайне. Всегда должен быть какой-то запас. На устойчивость. На развитие. В конечном итоге все упирается в "успевает - не успевает". Если один успевает на три такта быстрее, чем успевает другой, то конечный результат будет одним и тем же. Понятно, что хочется получить результат по максисмуму, но надо быть реалистами. Ни один МК, ни один компилятор не может быть лучше других по всем пунктам. Если бы это было так, то мы сейчас уже давно имели один МК и один компилятор для него..  По совокупности надо смотреть. И сравнивать тоже по совокупности.
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
|
Jun 22 2005, 01:24
|

Участник

Группа: Новичок
Сообщений: 47
Регистрация: 5-03-05
Пользователь №: 3 082

|
Цитата(dxp @ Jun 21 2005, 16:05) Непонятно, как Вы объявили переменные. Нужно, чтобы они были вместе объявлены, чтобы компилятор видел их одновременно. Если они в разных файлах объявлены, то, ессно, компилятор тут ничего поделать не сможет (даже если они реально попали в предел 64 байта один от другого), т.к. просто не знает, что они рядом и не может рулить их размещением. глобальные (видимые всем - не статик) переменные я объявляю в отдельном файле (думаю это рационально) global.c Код ... unsigned char blink_timer = 0; unsigned char Blink_Buffer[18]; ... аналогино с external обявляю в global.h , что и подключаю где надо. Код #include "iom8535.h" #include "global.h"
#pragma vector = TIMER2_OVF_vect __interrupt void system_timer(void) { blink_timer++; mySREG++; } Может ли это быть причиной непонимания компилятора?
|
|
|
|
|
Jun 22 2005, 04:30
|

Adept
     
Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343

|
Цитата(LeoLabs @ Jun 22 2005, 07:24) Цитата(dxp @ Jun 21 2005, 16:05) Непонятно, как Вы объявили переменные. Нужно, чтобы они были вместе объявлены, чтобы компилятор видел их одновременно. Если они в разных файлах объявлены, то, ессно, компилятор тут ничего поделать не сможет (даже если они реально попали в предел 64 байта один от другого), т.к. просто не знает, что они рядом и не может рулить их размещением. Цитата(LeoLabs @ Jun 22 2005, 07:24) глобальные (видимые всем - не статик) переменные я объявляю в отдельном файле (думаю это рационально) global.c Рациональность - понятие часто непонятное.  Объявлять переменные надо там, где они по смыслу нужны. Т.е. в тех модулях (единицах компиляции), которые для них основные. Для вытаскивания всех их в один файл должны быть какие-то отдельные причины. Цитата(LeoLabs @ Jun 22 2005, 07:24) Код ... unsigned char blink_timer = 0; unsigned char Blink_Buffer[18]; ... аналогино с external обявляю в global.h , что и подключаю где надо. Код #include "iom8535.h" #include "global.h"
#pragma vector = TIMER2_OVF_vect __interrupt void system_timer(void) { blink_timer++; mySREG++; } Может ли это быть причиной непонимания компилятора? Так и есть. У Вас обе переменные объявлены в другой единице компиляции, и компилятор просто не "видит" их - откуда ему знать при компиляции этого файла, что оба объекта находятся рядом? Он этого не знает, т.к. не сам их тут распределяет, поэтому не может делать никаких предположений об их взаимом положении, поэтому вынужден генерить при каждом обращении полный код. В общем, тут все в ваших руках. Если есть пачка глобальных объектов, связанных так или иначе - например, тем, что они подвергаются доступу в обработчике прерываний, поместите их в структуру. Тогда в любом случае они будут рядом, никакая кластеризация тут не нужна, доступ будет косвенным и эффективным. Подобные особенности архитектуры AVR и компилятора IAR для него в некоторой степени подталкивают пользователя к использованию агрегатных типов и объектов классов.
--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
|
|
|
|
Сообщений в этой теме
LeoLabs вопрос по IARy Jun 16 2005, 09:30 vet Цитата(LeoLabs @ Jun 16 2005, 13:30)Не пойму ... Jun 16 2005, 09:54 LeoLabs не верю! ну не может такого быть! Jun 17 2005, 04:22 vet Ещё немного сравнительных результатов от ICC v6.30... Jun 17 2005, 06:28 AlexOr Нет слов.
Только маты. Jun 20 2005, 13:28 vet Цитата(AlexOr @ Jun 20 2005, 17:41)Кстати,
LD... Jun 20 2005, 15:23  LeoLabs Задал этот вопрос (почему через указатели а не чер... Jun 21 2005, 01:12  vet Цитата(dxp @ Jun 21 2005, 10:35)Это до тех по... Jun 21 2005, 09:04   dxp Цитата(vet @ Jun 21 2005, 15:04)Прямо сейчас ... Jun 21 2005, 09:25    vet Цитата(dxp @ Jun 21 2005, 13:25)Цитата(vet ... Jun 21 2005, 10:03
4 чел. читают эту тему (гостей: 4, скрытых пользователей: 0)
Пользователей: 0
|
|
|