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

 
 
> вопрос по IARy, IAR спасовал?
LeoLabs
сообщение Jun 16 2005, 09:30
Сообщение #1


Участник
*

Группа: Новичок
Сообщений: 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? или я что-то не так пишу или хваленый иар не спосбен на подвиги?
ЧТО Я НЕ ТАК ДЕЛАЮ?
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
AlexOr
сообщение Jun 20 2005, 13:41
Сообщение #2


Частый гость
**

Группа: Свой
Сообщений: 89
Регистрация: 30-12-04
Из: Санкт-Петербург
Пользователь №: 1 754



Кстати,
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

но последнее в прерывании намного выгоднее (быстрее и менее расходно по регистрам).
Черт меня дернул сделать проект на IAR.
Сейчас взглянул на прологи/эпилоги и Ужаснулся.

Вопрос вдогонку:
Этот замечательный CodeVision умеет также легко работать с EEPROM как IAR?
Go to the top of the page
 
+Quote Post
dxp
сообщение Jun 21 2005, 06:35
Сообщение #3


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 рулит. smile.gif


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
LeoLabs
сообщение Jun 21 2005, 07:08
Сообщение #4


Участник
*

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



[/quote]

Не стОит так переживать из-за этой мелочи. Она погоду не делает совершенно. Наоборот, способность IAR'а приводить обращения к косвенным дает очень приличный выигрыш на деле. AVR-GCC имеет весьма неплохой кодогенератор, но он проигрывает IAR'у именно на этом моменте - AVR-GCC злоупотребляет lds/sts, из-за чего размер кода там получается больше.

*

[/quote]

Но прерывание ИАР слишком раздул, а надо то тока инкрементировать глобальную переменную. кстати это системный таймер и я думаю, что там не одна переменная может быть, но и несколько, а если они не подряд - то работа с указателями это только проигрыш.
Go to the top of the page
 
+Quote Post
dxp
сообщение Jun 21 2005, 07:36
Сообщение #5


Adept
******

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



Цитата(LeoLabs @ Jun 21 2005, 13:08)
Но прерывание ИАР слишком раздул, а надо то тока инкрементировать глобальную переменную. кстати это системный таймер и я думаю, что там не одна переменная может быть, но и несколько, а если они не подряд - то работа с указателями это только проигрыш.
*

Ну и сколько это байт оверхеда на фоне всего проекта? Сравнивайте весь проект (или хотя бы более-менее значимую часть), скомпиленные одним компиятором и другим.

Переменным не обязательно быть подряд. Им достаточно быть в пределах досягаемости указателя - 64 байта. Для того, чтобы они были вместе, достаточно их объявить вместе и включить оптимизацию clustering variables, которая, afair, включена по умолчанию.


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
LeoLabs
сообщение Jun 21 2005, 07:57
Сообщение #6


Участник
*

Группа: Новичок
Сообщений: 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


В чем дело то? может у меня завихрения?
да и в прерываниях, которые очень критичны к скорости, совсем ни к чему указатели. а по поводу памяти - то ее почти всегда хватит, напротив быстродействия всегда мало.
Go to the top of the page
 
+Quote Post
dxp
сообщение Jun 21 2005, 09:05
Сообщение #7


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. Хотя, думается, что если до сих пор не исправили, то это по той причине, что никого [из пользователей] этот факт особенно не волнует. Ведь и в самом деле, если работоспособность и устойчивость системы зависит от пары тактов, то тут явно что-то не то в дизайне. Всегда должен быть какой-то запас. На устойчивость. На развитие. В конечном итоге все упирается в "успевает - не успевает". Если один успевает на три такта быстрее, чем успевает другой, то конечный результат будет одним и тем же.

Понятно, что хочется получить результат по максисмуму, но надо быть реалистами. Ни один МК, ни один компилятор не может быть лучше других по всем пунктам. Если бы это было так, то мы сейчас уже давно имели один МК и один компилятор для него.. smile.gif По совокупности надо смотреть. И сравнивать тоже по совокупности.


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
LeoLabs
сообщение Jun 22 2005, 01:24
Сообщение #8


Участник
*

Группа: Новичок
Сообщений: 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++;
}

Может ли это быть причиной непонимания компилятора?
Go to the top of the page
 
+Quote Post
dxp
сообщение Jun 22 2005, 04:30
Сообщение #9


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

Рациональность - понятие часто непонятное. smile.gif Объявлять переменные надо там, где они по смыслу нужны. Т.е. в тех модулях (единицах компиляции), которые для них основные. Для вытаскивания всех их в один файл должны быть какие-то отдельные причины.

Цитата(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 для него в некоторой степени подталкивают пользователя к использованию агрегатных типов и объектов классов. smile.gif


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- 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


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

 


RSS Текстовая версия Сейчас: 19th July 2025 - 17:40
Рейтинг@Mail.ru


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