Форум обсуждения систем  

Вернуться   Форум обсуждения систем "Умный дом", проектов Ардуино, OpenWRT и других DIY устройств > Форум умного дома > Сделай сам

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
Старый 13.12.2013, 12:37   #1
sunjob
Member
 
Регистрация: 16.11.2013
Сообщений: 32
Вес репутации: 0
sunjob is an unknown quantity at this point
По умолчанию Ардуино, оптимизация условия if()

добрый день.

немного оптимизирую код, на данном этапе хочу попробовать заменить "условия" след. образом

#define BTN_A 1
#define BTN_B 2
#define BTN_C 3
#define BTN_D 4

if(BTN_PRESS == BTN_A)

-->

#define BTN_A 1
#define BTN_B 2
#define BTN_C 4
#define BTN_D 8

... в коде инициализация (BTN_PRESS - это не макрос, а переменная, для дотошных пусть будет беззнаковая целая)
BTN_PRESS = BTN_A
BTN_PRESS = BTN_В
BTN_PRESS = BTN_С
etc...

... битовая проверка условия
if(BTN_PRESS & BTN_A)

...

все бы хорошо пока "идентификаторов нажатий" было мало, вмещалось в байт.

дело дошло до:

#define BTN_A 1
#define BTN_B 2
#define BTN_C 4
#define BTN_D 8
#define ...
#define BTN_XXX 256
#define BTN_XXX 512
#define BTN_XXX 1024
#define ...

то есть дело дошло до 2х байт, а так как Atmega328P 8-битный, то возможны "осложнения-утяжеления" перехода на подобное "битное условие"

такое сокращение "процессорных команд и ускорение кода" в моем случае очень не помешает, практически необходимо

ВОПРОСЫ:
1. правильно ли я думаю, что проверка 2х байтного условия действительно утяжеляет код или на это можно забить?
2. на сколько утяжеляет?
3. какие подводные камни?
4. и вообще, правильно ли я мыслю, в том ли направлении?
5. ну... какие вообще мысли по этому поводу

п.с. я не монстр в программировании, поэтому с ассемблером не дружу, и на сколько "это" изменит машинный код пока не знаю :о)

спасибо заранее.

- проект собирается под Ардуино-IDE
- контроллер Atmega328P
- Linux, ну и все вытекающие моменты (NO WINDOWS)

Последний раз редактировалось sunjob; 13.12.2013 в 13:32.
sunjob вне форума   Ответить с цитированием
Старый 13.12.2013, 16:58   #2
SilverSwift
Senior Member
 
Регистрация: 21.09.2013
Сообщений: 109
Вес репутации: 0
SilverSwift is an unknown quantity at this point
По умолчанию Re: Ардуино, оптимизация условия if()

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

И вообще оптимизировать оператор для базовых типов сишным кодом нельзя. Можно писать на ассемблере или сделать ассемблерную вставку, но опять же прирост производительности сомнителен.

В одном байте можно хранить 256 значений, значит надо писать в BTN_PRESS не 1 битик, а число от 0 до 255. По времени тоже самое. Если битик формируется сдвиговыми командами то присвоение значения будет выполняться даже быстрее.
SilverSwift вне форума   Ответить с цитированием
Старый 13.12.2013, 19:08   #3
sunjob
Member
 
Регистрация: 16.11.2013
Сообщений: 32
Вес репутации: 0
sunjob is an unknown quantity at this point
По умолчанию Re: Ардуино, оптимизация условия if()

>> А где оптимизация?
читал что логическое условие по машинным кодам более длинное чем битовая операция (если не прав то поправьте и уточните)
sunjob вне форума   Ответить с цитированием
Старый 13.12.2013, 20:30   #4
sunjob
Member
 
Регистрация: 16.11.2013
Сообщений: 32
Вес репутации: 0
sunjob is an unknown quantity at this point
По умолчанию Re: Ардуино, оптимизация условия if()

собрал быстренько тест, результат следующий:
- "bool operation" - 882 bytes
- "binary operation" - 850 bytes

значит, все таки, оптимизация есть



#include <Arduino.h> //

// bool - 882 bytes
// binary - 850 bytes
//

#define BINARY_OPERATION

#define BTN_1 1
#define BTN_2 2
#define BTN_3 4
#define BTN_4 8
#define BTN_5 16
#define BTN_6 32
#define BTN_7 64
#define BTN_8 128
#define BTN_9 256
#define BTN_10 512
#define BTN_11 1024
#define BTN_12 2048

volatile int res = 0;
volatile int BTN_PRESS=0;

////////////////////////////////////////////////////////////////////////////////
void setup()
////////////////////////////////////////////////////////////////////////////////
{

#ifdef BINARY_OPERATION
BTN_PRESS = BTN_1; if(BTN_PRESS & BTN_1) res = BTN_1;
BTN_PRESS = BTN_2; if(BTN_PRESS & BTN_2) res = BTN_2;
BTN_PRESS = BTN_3; if(BTN_PRESS & BTN_3) res = BTN_3;
BTN_PRESS = BTN_4; if(BTN_PRESS & BTN_4) res = BTN_4;
BTN_PRESS = BTN_5; if(BTN_PRESS & BTN_5) res = BTN_5;
BTN_PRESS = BTN_6; if(BTN_PRESS & BTN_6) res = BTN_6;
BTN_PRESS = BTN_7; if(BTN_PRESS & BTN_7) res = BTN_7;
BTN_PRESS = BTN_8; if(BTN_PRESS & BTN_8) res = BTN_8;
BTN_PRESS = BTN_9; if(BTN_PRESS & BTN_9) res = BTN_9;
BTN_PRESS = BTN_10; if(BTN_PRESS & BTN_10) res = BTN_10;
BTN_PRESS = BTN_11; if(BTN_PRESS & BTN_11) res = BTN_11;
BTN_PRESS = BTN_12; if(BTN_PRESS & BTN_12) res = BTN_12;
#else
BTN_PRESS = BTN_1; if(BTN_PRESS == BTN_1) res = BTN_1;
BTN_PRESS = BTN_2; if(BTN_PRESS == BTN_2) res = BTN_2;
BTN_PRESS = BTN_3; if(BTN_PRESS == BTN_3) res = BTN_3;
BTN_PRESS = BTN_4; if(BTN_PRESS == BTN_4) res = BTN_4;
BTN_PRESS = BTN_5; if(BTN_PRESS == BTN_5) res = BTN_5;
BTN_PRESS = BTN_6; if(BTN_PRESS == BTN_6) res = BTN_6;
BTN_PRESS = BTN_7; if(BTN_PRESS == BTN_7) res = BTN_7;
BTN_PRESS = BTN_8; if(BTN_PRESS == BTN_8) res = BTN_8;
BTN_PRESS = BTN_9; if(BTN_PRESS == BTN_9) res = BTN_9;
BTN_PRESS = BTN_10; if(BTN_PRESS == BTN_10) res = BTN_10;
BTN_PRESS = BTN_11; if(BTN_PRESS == BTN_11) res = BTN_11;
BTN_PRESS = BTN_12; if(BTN_PRESS == BTN_12) res = BTN_12;
#endif
}
////////////////////////////////////////////////////////////////////////////////
void loop()
////////////////////////////////////////////////////////////////////////////////
{

}
////////////////////////////////////////////////////////////////////////////////

Последний раз редактировалось sunjob; 13.12.2013 в 20:40.
sunjob вне форума   Ответить с цитированием
Старый 14.12.2013, 00:28   #5
SilverSwift
Senior Member
 
Регистрация: 21.09.2013
Сообщений: 109
Вес репутации: 0
SilverSwift is an unknown quantity at this point
По умолчанию Re: Ардуино, оптимизация условия if()

BTN_PRESS = res; Вместо тысячи строк.

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

Обычно если одной железки не хватает для решения задачи нужно либо взять железку круче либо две таких же.
SilverSwift вне форума   Ответить с цитированием
Старый 14.12.2013, 15:01   #6
sunjob
Member
 
Регистрация: 16.11.2013
Сообщений: 32
Вес репутации: 0
sunjob is an unknown quantity at this point
По умолчанию Re: Ардуино, оптимизация условия if()

я вас услышал, но вопросы были такими:

1. правильно ли я думаю, что проверка 2х байтного условия действительно утяжеляет код или на это можно забить?
2. на сколько утяжеляет?
3. какие подводные камни?
4. и вообще, правильно ли я мыслю, в том ли направлении?
5. ну... какие вообще мысли по этому поводу

5й пункт это, конечно уже хорошо, но хотелось бы на все вопросы услышать ответы-мнения
sunjob вне форума   Ответить с цитированием
Старый 14.12.2013, 16:05   #7
Admin
Administrator
 
Аватар для Admin
 
Регистрация: 12.04.2010
Адрес: Москва
Сообщений: 9,618
Вес репутации: 9823
Admin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant futureAdmin has a brilliant future
По умолчанию Re: Ардуино, оптимизация условия if()

Цитата:
правильно ли я думаю, что проверка 2х байтного условия действительно утяжеляет код или на это можно забить?
1-Утяжеляет. Компилятор для этого использует 16 битный регистр
2- вы можете сами проверить
5 - Я пытался написать функции библиотеки CyberLib на ассемблере, но проверка показала что у компилятора Сишный код получается компактнее моего ассемблерного

Вот Вам пример цикла с условием, tic_us 16 битное значение :
Цитата:
void delay_us(uint16_t tic_us)
{
tic_us *= 40;
__asm__ volatile
(
"1: sbiw %0,1" "\n\t"
"brne 1b"
: "=w" (tic_us)
: "0" (tic_us)
);
}
Admin вне форума   Ответить с цитированием
Старый 14.12.2013, 21:50   #8
SilverSwift
Senior Member
 
Регистрация: 21.09.2013
Сообщений: 109
Вес репутации: 0
SilverSwift is an unknown quantity at this point
По умолчанию Re: Ардуино, оптимизация условия if()

1. То, что два байта занимают в памяти больше места, чем один должно быть очевидно.
2. То, что одна переменная занимает на 1 байт больше места должно быть также очевидно Глядя в предыдущий пример... 42 байта и 12 условий, итого каждая операция & на 3-4 байта короче операции ==.
3. Подводных камней в программировании нет, все прозрачно и описано в описаниях библиотек или в учебниках, все легко проверяется на практике во время отладки.
4. Не правильно. 4 байта которые дает использование другого оператора легко сожрет код с бОльшим количеством условий. Нужно менять структуру программы, кардинально. Либо брать другое железо.

Цитата:
Утяжеляет. Компилятор для этого использует 16 битный регистр
Таки регистры в ЦПУ, а в коде выделяется память для переменных, а тип переменной которую подставит компилятор зависит от многих условий.
SilverSwift вне форума   Ответить с цитированием
Ответ


Здесь присутствуют: 1 (пользователей: 0 , гостей: 1)
 

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

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.

Быстрый переход


Текущее время: 02:08. Часовой пояс GMT +3.


Powered by vBulletin® Version 3.8.5
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd. Перевод: zCarot
Яндекс.Метрика