03.02.2014, 08:58
|
|
Почётный гражданин KAZUS.RU
Регистрация: 06.08.2008
Адрес: Ярославль
Сообщений: 1,505
Сказал спасибо: 115
Сказали Спасибо 1,314 раз(а) в 548 сообщении(ях)
|
Re: CodeVisionAVR 2.60
Сообщение от Godzilla82
|
Ну если мыслить очень широко, то у вас простое сравнение, которое в случае изначального равенства переменной a нулю выполнится 1 раз.
|
Вы абсолютно правы. SasaVitebsk меня своим первоначальным вариантом с толку сбил, а я вчера с похмелья затупил.
Условие выхода из цикла - конечно же false, а не true.
Поэтому строчка должна выглядеть так.
for (;a›0;a--) TCNT0;
В этом случае компилятор AS действует грамотно.
Код:
|
#include ‹avr/io.h›
void del(int a)
{
for(;a›0;a--) TCNT0;
6c: 18 16 cp r1, r24
6e: 19 06 cpc r1, r25
70: 1c f4 brge .+6 ; 0x78 ‹del+0xc›
72: 22 b7 in r18, 0x32 ; 50
74: 01 97 sbiw r24, 0x01 ; 1
76: e9 f7 brne .-6 ; 0x72 ‹del+0x6›
78: 08 95 ret
0000007a ‹main›:
int main(void)
{
while(1)
{
del(100);
7a: 84 e6 ldi r24, 0x64 ; 100
7c: 90 e0 ldi r25, 0x00 ; 0
7e: 0e 94 36 00 call 0x6c ; 0x6c ‹del›
82: fb cf rjmp .-10 ; 0x7a ‹main›
00000084 ‹_exit›:
84: f8 94 cli
00000086 ‹__stop_program›:
86: ff cf rjmp .-2 ; 0x86 ‹__stop_program› |
Но повторюсь - такое решение абсолютно неочевидно.
Строчка
72: 22 b7 in r18, 0x32 ; 50
тут нафиг ненужна.
Последний раз редактировалось olc0267; 03.02.2014 в 09:29.
|
|
|
|
03.02.2014, 09:41
|
|
Почётный гражданин KAZUS.RU
Регистрация: 29.10.2006
Сообщений: 1,443
Сказал спасибо: 99
Сказали Спасибо 315 раз(а) в 231 сообщении(ях)
|
Re: CodeVisionAVR 2.60
Сообщение от olc0267
|
Строчка
72: 22 b7 in r18, 0x32 ; 50
тут нафиг ненужна.
|
Как это не нужна. Это тот самый камень преткновения, из-за которого комилятор не похерил всё нафиг вместе с процедурой.
|
|
|
|
03.02.2014, 10:02
|
|
Гражданин KAZUS.RU
Регистрация: 04.08.2006
Сообщений: 911
Сказал спасибо: 28
Сказали Спасибо 180 раз(а) в 139 сообщении(ях)
|
Re: CodeVisionAVR 2.60
Сообщение от _Артём_
|
Весьма спорные утверждения - всё зависит от ситуации и критерия эффективности.
|
Вы просто вырвали из контекста. Я именно о том и пишу, что рассматривать надо более глобально, а не только результирующий листинг. Учитывать нужно время потраченное на написание и поддержку, ясность и прозрачность программы, возможность заимствования, развиваемость проекта, переносимость проекта, возможность интеграции с проектами других разработчиков, возможность одновременной работы нескольких разработчиков над одним проектом, отлаживаемость и так далее ...
И если это начинаешь учитывать, то число минусов уменьшается а число плюсов растёт.
У меня сейчас один крупный проект на чистом си. Так вот жалею. Надо было бы на плюсах писать. ))
|
|
|
|
03.02.2014, 11:39
|
|
Почётный гражданин KAZUS.RU
Регистрация: 06.08.2008
Адрес: Ярославль
Сообщений: 1,505
Сказал спасибо: 115
Сказали Спасибо 1,314 раз(а) в 548 сообщении(ях)
|
Re: CodeVisionAVR 2.60
Сообщение от Godzilla82
|
Как это не нужна. Это тот самый камень преткновения, из-за которого комилятор не похерил всё нафиг вместе с процедурой.
|
А без этого никак? Я не вижу логики в том, что для того, чтобы заставить процессор потоптаться на месте, надо заставить его опросить порт в/в.
Компилятор обязан либо выполнить то, что ему написано, либо сообщить об ошибке. А он делает свои грязные делишки, и не считает нужным сообщить, что кусок кода выкинул. Ни единого ворнинга не вывел. А я потом должен волосы во всех местах рвать, гадая - почему программа не работает?
Нет, такой хоккей нам не нужен. Я лучше что попроще возьму. CV так по-свински не поступает.
Последний раз редактировалось olc0267; 03.02.2014 в 11:44.
|
|
|
|
03.02.2014, 15:36
|
|
Почётный гражданин KAZUS.RU
Регистрация: 29.10.2006
Сообщений: 1,443
Сказал спасибо: 99
Сказали Спасибо 315 раз(а) в 231 сообщении(ях)
|
Re: CodeVisionAVR 2.60
Сообщение от olc0267
|
Я не вижу логики в том, что для того, чтобы заставить процессор потоптаться на месте, надо заставить его опросить порт в/в.
|
Поэтому я привёл в самом начале пример, где вместо опроса порта используется ассемблерная команда "nop". Ну или volatile - кому как нравится.
Сообщение от olc0267
|
Компилятор обязан либо выполнить то, что ему написано, либо сообщить об ошибке. А он делает свои грязные делишки, и не считает нужным сообщить, что кусок кода выкинул. Ни единого ворнинга не вывел. А я потом должен волосы во всех местах рвать, гадая - почему программа не работает?
|
Мне это тоже в нём не нравится. Я и сам знаю, что цикл пустой. Раз написал - значит надо исполнить. Это не самое страшное. Он бывает выкидывает целые функции, только потому, что они ждут изменения переменной. А переменная меняется в прерывании. По логике ему надо просмотреть весь код - если она где-то меняется (тем более, в прерывании), то не "оптимизировать". Приходится объявлять переменную volatile. А это потеря тактов.
Сообщение от olc0267
|
Нет, такой хоккей нам не нужен. Я лучше что попроще возьму. CV так по-свински не поступает.
|
При вычислениях, особенно float и long у CV падает быстродействие.
На char и int он иногда оказывается быстрее GCC. Особенно при обработке коротких прерываний.
|
|
|
|
03.02.2014, 22:21
|
|
Почётный гражданин KAZUS.RU
Регистрация: 29.10.2012
Сообщений: 3,015
Сказал спасибо: 7
Сказали Спасибо 3,494 раз(а) в 1,783 сообщении(ях)
|
Re: CodeVisionAVR 2.60
Код:
|
#include ‹avr/io.h›
void delay (int s)
{
while (s) --s;
}
int main (void)
{
while (1)
{
delay(100);
}
} |
Код:
|
int main (void)
{
6e: 84 e6 ldi r24, 0x64 ; 100
70: 90 e0 ldi r25, 0x00 ; 0
void delay (int s)
{
while (s) --s;
72: 01 97 sbiw r24, 0x01 ; 1
74: f1 f7 brne .-4 ; 0x72 ‹main+0x4›
76: fb cf rjmp .-10 ; 0x6e ‹main› |
GCC.
|
|
|
|
03.02.2014, 22:48
|
|
Гражданин KAZUS.RU
Регистрация: 16.03.2011
Сообщений: 486
Сказал спасибо: 8
Сказали Спасибо 131 раз(а) в 116 сообщении(ях)
|
Re: CodeVisionAVR 2.60
Сообщение от Godzilla82
|
Я и сам знаю, что цикл пустой. Раз написал - значит надо исполнить.
|
Нет не надо - GCC,да и любой компилятор, который есть смысл обсуждать, является не просто компилятором, а оптимизирующим компилятором. Это как бы надо учитывать при написании программ.
Сообщение от Godzilla82
|
Это не самое страшное. Он бывает выкидывает целые функции, только потому, что они ждут изменения переменной.
|
Это потому что задача компилятора в том числе - оптимизация (если задано).
Сообщение от Godzilla82
|
А переменная меняется в прерывании. По логике ему надо просмотреть весь код - если она где-то меняется (тем более, в прерывании), то не "оптимизировать".
|
Это по Вашей логике. К тому же не всегда возможно "просмотреть весь код" - он может быть невидим для компилятора. Например зашит в бутлоадере и закрыт lock-битами (сделан другой фирмой, которая не раскрывает код). Как тогда код просматривать?
Сообщение от Godzilla82
|
Приходится объявлять переменную volatile. А это потеря тактов.
|
Нет никакой потери тактов - volatile указывает компилятору повторно считать переменную из ОЗУ в регистр (это к примеру - по-простому: чтобы считал занаво куда надо), а не работать со старой копией volatile-переменной.
Последний раз редактировалось _Артём_; 03.02.2014 в 22:52.
|
|
|
|
03.02.2014, 22:50
|
|
Гражданин KAZUS.RU
Регистрация: 16.03.2011
Сообщений: 486
Сказал спасибо: 8
Сказали Спасибо 131 раз(а) в 116 сообщении(ях)
|
Re: CodeVisionAVR 2.60
Сообщение от Арктур
|
[CODE]#include ‹avr/io.h›
GCC.
|
И что не так? GCC выкинул действия с переменными которые не нужны.Он не прав?
|
|
|
|
03.02.2014, 23:40
|
|
Почётный гражданин KAZUS.RU
Регистрация: 06.08.2008
Адрес: Ярославль
Сообщений: 1,505
Сказал спасибо: 115
Сказали Спасибо 1,314 раз(а) в 548 сообщении(ях)
|
Re: CodeVisionAVR 2.60
Сообщение от Godzilla82
|
При вычислениях, особенно float и long у CV падает быстродействие.
|
А какие задачи собираетесь выполнять с такими числами? АЦП у AVR - 10-ти
битный, максимальная дискретизация PWM - тоже 10 бит. Если делаете FFT с числом отсчётов 1024, то разрешение по оси Y нет смысла делать больше, чем по оси X, т.е. те же самые 10 бит. Если подключить внешний АЦП, например, DS18B20, так у него разрядность 12бит и интерфейс настолько медленный, что нет необходимости очень быстро считать floating point.
16-битного целочисленного представления для решения почти любой задачи на AVR должно хватать. Говорю "почти" потому, что не знаю, может, кто-то и придумает такую задачу.
Последний раз редактировалось olc0267; 03.02.2014 в 23:50.
|
|
|
|
03.02.2014, 23:50
|
|
Почётный гражданин KAZUS.RU
Регистрация: 06.08.2008
Адрес: Ярославль
Сообщений: 1,505
Сказал спасибо: 115
Сказали Спасибо 1,314 раз(а) в 548 сообщении(ях)
|
Re: CodeVisionAVR 2.60
Сообщение от Арктур
|
Код:
|
#include ‹avr/io.h›
void delay (int s)
{
while (s) --s;
}
int main (void)
{
while (1)
{
delay(100);
}
} |
Код:
|
int main (void)
{
6e: 84 e6 ldi r24, 0x64 ; 100
70: 90 e0 ldi r25, 0x00 ; 0
void delay (int s)
{
while (s) --s;
72: 01 97 sbiw r24, 0x01 ; 1
74: f1 f7 brne .-4 ; 0x72 ‹main+0x4›
76: fb cf rjmp .-10 ; 0x6e ‹main› |
GCC.
|
О! Вот это мне по душе! А мне тут впаривали, что без опроса порта и volatile никак низзя.
А как так получилось? Где вызов функции delay, и возврат из неё? Компилятор слил две функции в одну - вот это оптимизация!
|
|
|
|
Ваши права в разделе
|
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения
HTML код Выкл.
|
|
|
Часовой пояс GMT +4, время: 17:25.
|
|