roboforum.ru

Технический форум по робототехнике.
Текущее время: 17 фев 2025, 06:54

Часовой пояс: UTC + 4 часа




Начать новую тему Ответить на тему  [ Сообщений: 16 ]  На страницу 1, 2  След.
Автор Сообщение
 Заголовок сообщения: Объявление переменной в середине кода функции.
СообщениеДобавлено: 11 дек 2015, 13:28 
Не в сети

Зарегистрирован: 11 дек 2015, 13:09
Сообщения: 6
У меня откуда-то отложилась информация о том, что где-бы не была объявлена переменная в коде на машином языке она будет инициализирована при входе в функцию. Как с этим дела на ATMega обстоят? Я в прерывании, какой код будет быстрее выходить из прерывания, в случае, когда в if ложно:
1.
Код:
ISR(TIMER1_CAPT_vect) {
  unsigned int timer1CounterValue;
  timer1CounterValue = ICR1;
  if (timer1CounterValue < 0x7FFF) {
    unsigned long a = действия с глобальной переменной;
    ...
  };

3.
Код:
ISR(TIMER1_CAPT_vect) {
  unsigned int timer1CounterValue;
  timer1CounterValue = ICR1;
  unsigned long a;
  if (timer1CounterValue < 0x7FFF) {
    a = действия с глобальной переменной;
    ...
  };


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Объявление переменной в середине кода функции.
СообщениеДобавлено: 11 дек 2015, 13:42 
Не в сети

Зарегистрирован: 03 янв 2012, 12:55
Сообщения: 3298
Откуда: Москва
прог. языки: VB6, BASCOM, ASM...
дизассемблируйте код или в дебейгере посмотрите, если компилятор грамотный, то разницы не должно быть
если вам так критична скорость выполнения в прерывании, то переходите на ASM

зы: все эти языковые замуты МК пофиг, все проблемы от компилятора (если они есть). Т.ч. тут "ATMega" и XMega, ARMы...не важно.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Объявление переменной в середине кода функции.
СообщениеДобавлено: 11 дек 2015, 14:30 
Не в сети

Зарегистрирован: 11 дек 2015, 13:09
Сообщения: 6
Я этого не умею делать, asm пока не знаю. Если кому то знающему не сложно, то просьба проверить.
Спасибо.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Объявление переменной в середине кода функции.
СообщениеДобавлено: 11 дек 2015, 14:59 
Не в сети
Аватара пользователя

Зарегистрирован: 18 апр 2009, 22:18
Сообщения: 10668
из-за пары тактов целую тему подняли? дык барин если не знаете асм, так и нечего такими вопросами голову себе забивать. варианта два - начинайте изучать асм, дизасемблирование, архитектуру конкретных мк, отличия компиляторов и влияние настроек. или прекращайте задаваться бессмысленными вопросами. "Если кому то знающему не сложно, то просьба проверить" ещё раз намекаю, что разные компиляторы и/или с разными настройками могут по разному компилировать. "..." в данном огрызке кода означает, что даже нельзя предсказать, компилятор вообще выкинет эту "a" и присваивание ей или нет. :pardon: оптимизация однако. когда нужно каждый такт беречь, так код не на си пишется, а на асме. так что учите и асм вставочками делайте. и это, си продолжайте изучать - называть локальную переменную глобальной о многом говорит...


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Объявление переменной в середине кода функции.
СообщениеДобавлено: 11 дек 2015, 15:43 
Не в сети

Зарегистрирован: 11 дек 2015, 13:09
Сообщения: 6
Я не берегу каждый такт, но и раскидываться ими, особенно где код выполняется десяток раз за миллисекунду, не хочется. Но вообще при программировании придерживаюсь некоторых правил, по которым компилятор МОЖЕТ оптимизировать. Просто использую эти правила для увеличения быстродействия, а если компилятор этот момент не оптимизирует, исправить это не смогу, но каждый раз проверять стоит ли использовать это правило с компилятором для оптимизации или нет, не буду, просто буду этого правила придерживаться. К примеру, знаю, что с некоторыми компиляторами при условии if с ИЛИ, если первое выражение true, второе уже не проверяется, поэтому на первое место ставлю то выражение, которое по моим представлениям чаще другого истинно. При этом я не знаю как ведёт себя avr компилятор и использует ли такую оптимизацию. Вообще до AVR я программировал только на Object Pascal, Free Pascal. А тут в Си заинтересовала возможность объявления переменных перед первым использованием. Так код намного лучше понимаем и комментировать проще.
Из того, что удалось выяснить. Если команды asm
Код:
cpc     r25, r1
brcc    .+24

это и есть сравнение и прыжок при "false", то разницы никакой, сравнение происходит на одной и той же по счёту инструкции. Но вот размер скомпилированной программы отличается. Скомпилированная программа с объявлением переменной в начале функции, а не перед первым использованием, почему-то на 20 байтов меньше. Как в gdb дизассемблировать всю программу, а не только функцию, я пока не нашёл.
В итоге, моё исследование показало, что объявление переменной перед её использованием в блоке if на скорость до if не влияет, а вот размер программы увеличивает, почему-то. А размер программы для контролера критичен. Так что лучше объявлять переменные в начале. ИМХО. Но исследование может быть ошибочно в силу не знания asm для котроллера avr.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Объявление переменной в середине кода функции.
СообщениеДобавлено: 11 дек 2015, 16:06 
Не в сети

Зарегистрирован: 03 янв 2012, 12:55
Сообщения: 3298
Откуда: Москва
прог. языки: VB6, BASCOM, ASM...
Если вы пишите на си под атмегу, то наверняка это Авр Студия, там есть симулятор/дебайгер: https://www.youtube.com/watch?v=aAw-7Lq-3tI
Можете не зная ASM-а, просто посмотреть по тактам/времени сколько выполняется функция в разных её представлениях...


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Объявление переменной в середине кода функции.
СообщениеДобавлено: 12 дек 2015, 00:24 
Не в сети

Зарегистрирован: 11 дек 2015, 13:09
Сообщения: 6
Спасибо.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Объявление переменной в середине кода функции.
СообщениеДобавлено: 12 дек 2015, 04:04 
Не в сети
Аватара пользователя

Зарегистрирован: 13 янв 2011, 15:25
Сообщения: 8033
Откуда: Санкт-Петербург
viper писал(а):
Я в прерывании, какой код будет быстрее выходить из прерывания, в случае, когда в if ложно:

Код в 2-х примерах логически одинаковый. И что значит "a = действия с глобальной переменной;"? Если бы "глобальная переменная = a;" еще понятно, если "глобальная переменная = действия с локальной переменной;" опять непонятно, почему вообще справа от равно есть действо? :shock: В фразе "действия с глобальной переменной" находится весь смысл вопроса, а тема сисек не раскрыта. Это неправильно, нехорошо, нелогично. Тем более для прерываний. :)
Си в каких-то версиях начинает разрешать обьявление переменных в середине кода, ибо код с обьявлением в начале функции несильно уходит от асмовского программописания. Если откомпилить: for(int a = 0;....) в нормальных компиляторах, то будет/не будет ошибка в зависимости от флага "-std=gnu99". Как это делается в иде для лохов (платных закрытых) надо уточнять у разработчиков, т.е. звонок другу в службу поддержки, ну если не крякнутый/ворованный компилятор :)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Объявление переменной в середине кода функции.
СообщениеДобавлено: 12 дек 2015, 05:26 
Не в сети
Аватара пользователя

Зарегистрирован: 18 апр 2009, 22:18
Сообщения: 10668
объявление лонга до условия и после это как раз возня ради пары тактов. "if с ИЛИ ..." аха, размечтались. с или оно может проверить всё, а вот с или или брякает на первом тру. "но каждый раз проверять стоит ли использовать это правило с компилятором для оптимизации или нет, не буду, просто буду этого правила придерживаться" ну и ... (сам придумай, ибо со второго раза не доходит про компиляторы и настройки, а это следствие действия тормозной жидкости). в отличии от мира фантазий, в реальном мире с такой логикой вас ждут шишки на лбу и множество не очевидных вам вещей, возможно с неприятными сюрпризами. и это только компилятор, а ещё у разных камушков есть море приятных различий в архитектуре, что по глупости недоучек-оптимизаторофф легко может приводит к противоположному от желаемого эффекту. для тугоплавких повторяю элементарные азы - когда для таких хилых и примитивных мк нужно оптимизировать, то это делается на асме и только на асме - в следующем билде компилятора или студии что-то поменяется и всё, ваши все недооптимизации могут пойти в одно место, а вы об этом скорей всего даже и не узнаете. банально скопипастили код из студии в другую, а там или компилятор другой или настройки, весело... и ещё момент - оптимизируют только когда это необходимо, оптимизация ради оптимизации это не оправдано затратно, неэффективно и т.д., т.е. тупо, особенно с нулевыми знаниями и опытом. а самое смешное, когда долго и нудно некоторые тужатся с оптимизацией, а потом где в коде возьмут, да и вызовут допустим тяжеловесную библиотечную функцию, которая слопает на порядок больше тактов и/или памяти. а кроме функций ещё много чего интересного есть - типы данных, операции над переменными (банально да хоть деление или умножение, когда камушек это не умеет) и т.д. но упёршись рогами и вникая во всякую фигню вы о многих вещах или не скоро узнаете или не узнаете вообще и никогда. пока только очень заметно, что даже элементарные азы языка ещё не осилили, а уже лезите в ненужные дебри. печальное зрелище с предсказуемым результатом.
Dmitry__, с каких-то версий некоторые компиляторы вообще-то стали очень навороченными и интеллектуальными. хотя ещё не настолько интеллектуальные - с таким кодом оте дополнительные 20 байт это наверно первые робкие и неудачные попытки сделать локальную переменную глобальной.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Объявление переменной в середине кода функции.
СообщениеДобавлено: 20 дек 2015, 01:29 
Не в сети

Зарегистрирован: 11 дек 2015, 13:09
Сообщения: 6
Angel71
Интересная у Вас манера общения, сразу с каких-то оскорблений.
Я честно говоря, так и не понял, почему вы упорно утверждаете, что я не знаю что такое глобальная переменная.
Код:
unsigned long a = действия с глобальной переменной;

Это значит, что есть объявленная глобальная переменная, пусть её название будет global, а в выделенном участке кода пусть будет присвоение локальной переменной квадрата глобальной. Итого:
Код:
unsigned long a = global*global;

Хотя нет, я догадываюсь, почему вы не поняли пример, видимо из-за малой практики, вы подумали, что я хотел привести пример вида:
Код:
unsigned long a = a*a;
, и называл переменную глобальной, так как, с ваших слов, не осилил элементарные азы языка. Но будь у вас достаточно практики, вы бы поняли, что такие действия бесполезны и не возможно получить ожидаемый результат, он будет не предсказуемый, так как переменная а не инициализирована, и что бы не было справа с участием этой переменной, результат будет иметь случайное значение. То есть такая строка вообще никакого смысла не имеет, сразу уж можно было написать
Код:
unsigned long a = 100500;


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Объявление переменной в середине кода функции.
СообщениеДобавлено: 20 дек 2015, 05:14 
Не в сети
Аватара пользователя

Зарегистрирован: 18 апр 2009, 22:18
Сообщения: 10668
т.е. "unsigned long a = действия с глобальной переменной;" не может означать, допустим такое "static uint32_t a += diff;"?
Код:
volatile uint8_t counter;
volatile uint16_t start, diff;

ISR(TIMER1_CAPT_vect)
{
   if (TCCR1B & 0x40) { TCCR1B &= ~0x40; start = ICR1; }
   else {
      TCCR1B |= 0x40;
      if (!(counter & 0x80)) {
         diff = ICR1;
         if (start > diff)
            diff += TOP;
         diff -= start;
         if (diff > MIN && diff < MAX)
         {
            if ((counter&(~0x80)) < 30) counter += 3;
         }
         else counter &= 0x80;
      }
   }
   static float a = a * 0.5 + (float)(counter) * 0.5;
}

значение не инициализированных переменных всегда не известны? :crazy: а, точно, разрабы реализовали забивание памяти рандомом при старте мк. есть и другие варианты, при старте будут старые или "повреждённые" данные. хотя... :ROFL: такому опытному человегу как вы, напоминать про такие мелочи каг бэ рановато - всё связанное с си и работой горстки мк с различными архитектурами если на жалкий десяток % и изучил, то уже хорошим результатом считаю.


Последний раз редактировалось Angel71 20 дек 2015, 05:49, всего редактировалось 1 раз.

Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Объявление переменной в середине кода функции.
СообщениеДобавлено: 20 дек 2015, 05:49 
Не в сети
Аватара пользователя

Зарегистрирован: 13 янв 2011, 15:25
Сообщения: 8033
Откуда: Санкт-Петербург
Angel71 писал(а):
т.е. "unsigned long a = действия с глобальной переменной;" не может означать, допустим такое "static uint32_t a += diff;"?

Тема сисек раскрыта :)

viper, а если я не оскорблял, пачиму нет ответов на мои вопросы? :cry:


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Объявление переменной в середине кода функции.
СообщениеДобавлено: 20 дек 2015, 06:21 
Не в сети
Аватара пользователя

Зарегистрирован: 18 апр 2009, 22:18
Сообщения: 10668
ну да, раскрыта. а вдруг там после равно "Singleton::getInstance().time->getTime();" :crazy: поди разбери, что у него там за действия с глобальными переменными могут быть.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Объявление переменной в середине кода функции.
СообщениеДобавлено: 20 дек 2015, 20:15 
Не в сети

Зарегистрирован: 11 дек 2015, 13:09
Сообщения: 6
Цитата:
т.е. "unsigned long a = действия с глобальной переменной;" не может означать, допустим такое "static uint32_t a += diff;"?

Я разве static указывал перед объявлением переменной? Нет не может, фантазии могут быть справа от равно.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Объявление переменной в середине кода функции.
СообщениеДобавлено: 21 дек 2015, 03:06 
Не в сети
Аватара пользователя

Зарегистрирован: 18 апр 2009, 22:18
Сообщения: 10668
а, так вон оно чё, михалыч. раз хочешь, так и дальше возись с потугами оптимизации без оптимизации и почаще продолжайте игнорировать вещи, влияющие на генерируемый машинный код.


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 16 ]  На страницу 1, 2  След.

Часовой пояс: UTC + 4 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 0


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Перейти:  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB
phpBB SEO