Easyelectronics.ru

Электроника для всех
Текущее время: 11 авг 2020, 03:46

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



JLCPCB – Прототипы печатных плат за $2/5шт. два слоя. $5/5шт. четыре слоя
Крупнейший производитель печатных плат и прототипов. Более 600000 клиентов и свыше 10000 заказов в день!
Получите скидку на почтовую отправку при первом заказе в JLCPCB!

Начать новую тему Ответить на тему  [ Сообщений: 20 ] 
Автор Сообщение
 Заголовок сообщения: с++ if или switch
СообщениеДобавлено: 02 дек 2016, 09:09 
Только пришел

Зарегистрирован: 02 дек 2016, 08:29
Сообщения: 5
Есть кусок кода в прерывании, скорость выполнения критична. Контроллер 8 бит.
switch (ncv)
{
case 1:
if (uk>=360-uop)
{
PORTD|=(1<<4);
TCNT0=0;
ncv=2;
}
break;
и Т.Д.
переменная uk 16 битная, дабы не нагружать вычислениями, решено ввести 8 битную (ncv)
Но тут проблема case 1: выполнится немного быстрее case 4:
если вместо этого использовать:
if ((ncv==1)&&(uk>=360-uop));
будет медленней, зато ровно.
Вопрос: в этом сравнении первым проверяется (ncv==1) и (uk>=360-uop) игнорируется, если (ncv==1) ложь?
Одно из (ncv==***) в прерывании всегда истина но (uk>=***-uop) нет, и прерывание холостое.
Т.Е. весь смысл в проверке (uk>=***-uop)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: с++ if или switch
СообщениеДобавлено: 02 дек 2016, 09:38 
Старожил

Зарегистрирован: 16 ноя 2012, 07:47
Сообщения: 2872
Если критична скорость до такта, может на асме переписать? В данном случае, логическое И считается слева-направо, если верить Кернигану. Как это развернул компилятор - еще вопрос.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: с++ if или switch
СообщениеДобавлено: 02 дек 2016, 11:25 
Старожил
Аватара пользователя

Зарегистрирован: 29 янв 2010, 15:41
Сообщения: 1127
Откуда: Германия
VITAL_P писал(а):
Вопрос: в этом сравнении первым проверяется (ncv==1) и (uk>=360-uop) игнорируется, если (ncv==1) ложь?

По стандартам С и С++, условия проверяются с лева на право, и если в этой очереди что-то не true, то проверка прерывается.
Поэтому, например, вполне безопасно в одном if проверить указатель на валидность, а потом обратиться к нему:
if( ptr && (ptr->abc == 10)) {...}
И в основном так и делают.
Если вдруг разрабы компилятора поменяют этот момент, то "начнут падать самолеты" ;-)

В конструкциях типа
if ((ncv==1)&&(uk>=360-uop))
всегда желательно расставлять скобки:
if ((ncv==1)&&(uk>= ( 360-uop ) ))
Иначе может статься так, что разрабы поменяют приоритет операций, и увас вместо того, что вы имели ввиду, сначала вычислится булевое выражение и потом от 0 или от 1 отнимется uop.

Ну и в третьих - по скорости switch быстрее, по месту во флеше if вроде как компактнее, но начиная с трех case switch начинает быть еще компактнее :) Но то было еще в мои времена аврок.

_________________
Мои поделки
http://www.fun-electronic.net/


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: с++ if или switch
СообщениеДобавлено: 02 дек 2016, 11:40 
Старожил
Аватара пользователя

Зарегистрирован: 30 мар 2015, 23:56
Сообщения: 819
switch работает быстро при входных параметрах целого числа от 0 в + и без пропусков. В этом случае на асме будет табличный переход, без проверки каждого сравнения.

if ((ncv==1)&&(uk>=360-uop)); на асме выглядит как условные переходы от сравнения. Но после оптимизации gcc подменяет саму функцию сравнения (ncv==1) на (ncv!=1) с целью шагнуть сразу к else. В этом случае проверка условия >= требует большего количества кода, если будет первым в функции.

_________________
Потоковая OS


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: с++ if или switch
СообщениеДобавлено: 02 дек 2016, 11:42 
Старожил

Зарегистрирован: 16 ноя 2012, 07:47
Сообщения: 2872
Не все вычисляются слева-направо. Есть исключения http://ad.cctpu.edu.ru/cpp/glava3_10.htm


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: с++ if или switch
СообщениеДобавлено: 02 дек 2016, 13:03 
Старожил
Аватара пользователя

Зарегистрирован: 29 янв 2010, 15:41
Сообщения: 1127
Откуда: Германия
Hold писал(а):
Не все вычисляются слева-направо. Есть исключения http://ad.cctpu.edu.ru/cpp/glava3_10.htm

по вашей же ссылке
Цитата:
12 && И - логическое слева - направо
13 || ИЛИ - логическое слева - направо

Ведь речь идет о операндах оператора if. Не так ли?

_________________
Мои поделки
http://www.fun-electronic.net/


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: с++ if или switch
СообщениеДобавлено: 02 дек 2016, 13:04 
Старожил

Зарегистрирован: 16 ноя 2012, 07:47
Сообщения: 2872
виноват, не заметил ваше слово "...УСЛОВИЯ проверяются...". Да, именно так.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: с++ if или switch
СообщениеДобавлено: 02 дек 2016, 13:12 
Старожил

Зарегистрирован: 23 янв 2016, 15:37
Сообщения: 1240
MasterAlexei писал(а):
В конструкциях типа
if ((ncv==1)&&(uk>=360-uop))
всегда желательно расставлять скобки:
if ((ncv==1)&&(uk>= ( 360-uop ) ))
Иначе может статься так, что разрабы поменяют приоритет операций, и увас вместо того, что вы имели ввиду, сначала вычислится булевое выражение и потом от 0 или от 1 отнимется uop.

Приоритеты операций не меняются никогда, даже при переходе с С на С++ новые операции втиснули между старыми, но относительный порядок последних не изменился.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: с++ if или switch
СообщениеДобавлено: 02 дек 2016, 13:39 
Старожил
Аватара пользователя

Зарегистрирован: 29 янв 2010, 15:41
Сообщения: 1127
Откуда: Германия
Reflector писал(а):
MasterAlexei писал(а):
В конструкциях типа
if ((ncv==1)&&(uk>=360-uop))
всегда желательно расставлять скобки:
if ((ncv==1)&&(uk>= ( 360-uop ) ))
Иначе может статься так, что разрабы поменяют приоритет операций, и увас вместо того, что вы имели ввиду, сначала вычислится булевое выражение и потом от 0 или от 1 отнимется uop.

Приоритеты операций не меняются никогда, даже при переходе с С на С++ новые операции втиснули между старыми, но относительный порядок последних не изменился.

Эти приоритеты не меняются до тех пор, пока они именно с "чистыми" переменными рядом стоят. А то какой нить новый разраб придет и поменяет, например, переменную uop на макрос
#define uop a + b / (c - d)
забыв при этом скобки везде расставить. И иди потом гадай и ищи, где оно не так работает, Причем "вдруг".
А поменял потому, что не хотел перелопачивать весь код, где эта переменная встречается, ну и чтоб потом статистику по измененным файлам не портить :)

Напарывался на такие моменты не раз, и не два. Потому знаю, что это такое на самом деле.

В общем - скобки не зря придумали. Макросы - зло. все if-ы по одному условию и в одну строчку! :) :) :)

_________________
Мои поделки
http://www.fun-electronic.net/


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: с++ if или switch
СообщениеДобавлено: 02 дек 2016, 13:45 
Старожил
Аватара пользователя

Зарегистрирован: 24 июл 2012, 13:54
Сообщения: 856
Благодарю за разъяснения по порядку использования проверок с логическим &&
Цитата:
if( ptr && (ptr->abc == 10)) {...}

Ранее я знал, что так можно писать, но не понимал, почему, в силу чего старательно избегал таких конструкций.

Теперь перестану это делать :).


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: с++ if или switch
СообщениеДобавлено: 02 дек 2016, 13:51 
Старожил

Зарегистрирован: 23 янв 2016, 15:37
Сообщения: 1240
MasterAlexei писал(а):
Эти приоритеты не меняются до тех пор, пока они именно с "чистыми" переменными рядом стоят. А то какой нить новый разраб придет и поменяет, например, переменную uop на макрос
#define uop a + b / (c - d)
забыв при этом скобки везде расставить. И иди потом гадай и ищи, где оно не так работает, Причем "вдруг".
А поменял потому, что не хотел перелопачивать весь код, где эта переменная встречается, ну и чтоб потом статистику по измененным файлам не портить :)

Это да, но изначально речь шла о том, что разрабы поменяют приоритет операций, а это могут делать только разрабы компиляторов :) А макросы нужно сами в скобки оборачивать, тогда не придется их лепить при каждом использовании:
#define uop (a + b / (c - d))
Иначе даже в простейших случаях вместо "a + b * c" придется везде писать "a + (b * c)", а это уже явный перебор :) Лично у меня таких проблем нет, я за последний год использовал макрос 1 раз :)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: с++ if или switch
СообщениеДобавлено: 02 дек 2016, 13:56 
Старожил
Аватара пользователя

Зарегистрирован: 29 янв 2010, 15:41
Сообщения: 1127
Откуда: Германия
Reflector писал(а):
Это да, но изначально речь шла о том, что разрабы поменяют приоритет операций, а это могут делать только разрабы компиляторов :) А макросы нужно сами в скобки оборачивать, тогда не придется их лепить при каждом использовании:
#define uop (a + b / (c - d))
Иначе даже в простейших случаях вместо "a + b * c" придется везде писать "a + (b * c)", а это уже явный перебор :)

Согласен.

Reflector писал(а):
Лично у меня таких проблем нет, я за последний год использовал макрос 1 раз :)

Везет. ...но не верю. :)
Все используют макросы, только не замечают этого. Достаточно глянуть на какой нить хедер от той же ST. Там этими макросами все прямо таки угажено :) Но это уже не в тему и можно будет потом грохнуть.

_________________
Мои поделки
http://www.fun-electronic.net/


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: с++ if или switch
СообщениеДобавлено: 02 дек 2016, 14:02 
Старожил

Зарегистрирован: 23 янв 2016, 15:37
Сообщения: 1240
MasterAlexei писал(а):
Везет. ...но не верю. :)
Все используют макросы, только не замечают этого. Достаточно глянуть на какой нить хедер от той же ST. Там этими макросами все прямо таки угажено :) Но это уже не в тему и можно будет потом грохнуть.

В стандартных хедерах макросы понятное дело присутствуют, но там они уже в скобках. Я говорил о самописных, но мне проще, у C++ как минимум есть шаблоны и нормальные константы :)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: с++ if или switch
СообщениеДобавлено: 02 дек 2016, 19:29 
Старожил
Аватара пользователя

Зарегистрирован: 24 июл 2012, 13:54
Сообщения: 856
К слову, любопытная техника написания макросов была обнаружена в коде ядра embox:

Код:
/** @return A @a val limited to a boundary specified by @a lo and @a hi. */
#define clamp(val, lo, hi) \
   ({                                          \
      typeof(val) __clamp_val = (val);        \
      typeof(lo)  __clamp_lo  = (lo);         \
      typeof(hi)  __clamp_hi  = (hi);         \
      __clamp_val < __clamp_lo ? __clamp_lo : \
      __clamp_val > __clamp_hi ? __clamp_hi : \
      __clamp_val;                            \
   })


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: с++ if или switch
СообщениеДобавлено: 02 дек 2016, 20:51 
Только пришел

Зарегистрирован: 02 дек 2016, 08:29
Сообщения: 5
Спасибо всем за ответы.
Может я, просто выбрал не самый быстрый путь решения задачи?...
Упрощенно: Есть некая шестеренка 360 зубов (их там меньше) с изменяемой скоростью вращения. И датчик который выдаёт импульсы в МК каждый градус поворота.
Есть некие строго повторяющиеся события "ncv". У каждого события есть приблизительный угол выполнения ± "uop" переменная "uk" это как раз угол (посчитанный)
if ((ncv==1)&&(uk>=360-uop));
угол "uk" может быть не только до 360º но, и 720... 2 оборота и больше.
Устройство работает в допусках (нестабильность выполнения PORTD|=(1<<4); 2-3%)
Но как всегда хочется улучшить. А если в дальнейшем событий придется добавить? Вот и решил поковырять этот кусок кода.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: с++ if или switch
СообщениеДобавлено: 03 дек 2016, 15:09 
Заглядывает иногда

Зарегистрирован: 15 ноя 2015, 12:11
Сообщения: 193
Reflector писал(а):
Приоритеты операций не меняются никогда, даже при переходе с С на С++ новые операции втиснули между старыми, но относительный порядок последних не изменился.

В C++ тернарную понизили.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: с++ if или switch
СообщениеДобавлено: 05 дек 2016, 04:42 
Старожил

Зарегистрирован: 17 дек 2014, 04:38
Сообщения: 703
Попробуйте массив указателей на функции - самый быстрый способ. Так как сравнения не происходит, просто вызывается функция по индексу из таблицы


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: с++ if или switch
СообщениеДобавлено: 07 дек 2016, 09:26 
Старожил

Зарегистрирован: 06 фев 2011, 15:16
Сообщения: 617
Откуда: Челябинск
VITAL_P писал(а):
Вопрос: в этом сравнении первым проверяется (ncv==1) и (uk>=360-uop) игнорируется, если (ncv==1) ложь?
Да! Это определено стандартом языка.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: с++ if или switch
СообщениеДобавлено: 27 дек 2016, 13:28 
Старожил
Аватара пользователя

Зарегистрирован: 24 июл 2012, 13:54
Сообщения: 856
Я бы реализовал это так:
Во первых, не стал делать переменную угол в диапазоне 0-360. Пусть лучше она растет вверх без обнуления.

При каждой инкриментации датчика проверяется, не достигли ли мы точки события.
Если достигли, или устанавливается соответствующий флаг, или сразу вызывается обработчик.

Обработчик события в том числе вычисляет и устанавливает новую точку события.
Если различных типов событий немного, можно использовать несколько разных точек событий и проверять их последовательно.
Если же их много, то я бы реализовал логику выбора ближайшего по списку и проверял бы только его.

Как-то так. Вот что мне точно не нравится, так это "приблизительный" угол. Аппаратная часть должна считать целочисленно в отсчетах датчика и тригериться точно по отсчету. А округления и расчеты угла можно отдать на откуп логике вычисления следующей точки.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: с++ if или switch
СообщениеДобавлено: 27 дек 2016, 20:50 
Старожил
Аватара пользователя

Зарегистрирован: 18 май 2013, 20:43
Сообщения: 4866
Откуда: Кемеровская область, Киселевск
Код дизассемблера покажите а там видно будет, вы напишите одно, а компилятор может интерпретировать по своему усмотрению.

_________________
RADIOWOLF.RU


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 20 ] 


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


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

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


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

Найти:
Перейти:  

Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB