Страница 1 из 3
Оптимизация создаваемой программы, использование блоков
Добавлено: 20.01.2018{, 12:56}
Sancho
Возможно, не в том разделе пишу, просто это начало того, что крутится сейчас в голове...
Мы уже как-то привыкли, что всё работает в FLProg как есть, и ничего не хотим менять.
Но вот наступает момент, когда надо чего-то добавить, и наша программа после "апгрэйдов" начинает тупить, тормозить и т.д.
Вопрос "почему?" не может иметь однозначного ответа, пока мы не посмотрим, что имеем в итоге, т.е. код.
Но не все спецы в этом деле, в том числе и я.
Сам код в Ардуино IDE тоже не отличается особой читабельностью, а о режимах и методах работы компилятора и выполнения инструкций в самом контролере я вообще только слышал.
Выход один - использовать сторонние библиотеки, ну и конечно учится понимать язык С++.
Изучение каждый понимает по своему, но к этому когда нибудь, да придёт почти каждый. (даже я в свои 46 пришёл)
Иногда, немного набравшись опыта, посмотришь код - куча ненужного, начинаешь убирать. Освобождается место в памяти, уменьшается сам объём программы...
Буквально на днях, начав пилить блок для "фазорезки" на восемь каналов по модбас, проведя несколько опытов, я понял, что скорости выполнения цикла мне не хватит, прерывания ещё не осилил толком. Слышал о работе с регистрами, начал искать информацию.
А нашёл интереснейшую библиотеку.
Огромное СПАСИБО её разработчикам!!!
Сделал
Пользоательские Блоки для нашей программы.
Результаты генератора с ООС ( отрицательной обратной связью), пин 2 и 12 соединены
Отправлено спустя 44 минуты 1 секунду:
Пока не забанили за флуд - продолжу.
Добавили быстрые входы - хорошо, ускорилось. Но.
Если мы уберём в полученном коде "лишние", промежуточные переменные, которые всегда возникают при использовании ПБ,
и приведём код от
Код: Выделить всё
IN_2 =D2_Read;
_out_12_ = !(IN_2);
if ( _out_12_ ) D12_High;
if ( ! _out_12_ ) D12_Low;
к виду
Код: Выделить всё
if ( !D2_Read ) D12_High;
if ( D2_Read ) D12_Low;
то получим 554 / 13 байт и 884,6 кГц!
Это ни в коем случае не значит, что программа с использованием этих блоков ускорится в 5-10 раз, т.к. в ней ещё присутствует много всего, но время выполнения цикла сократится однозначно!
Оптимизация создаваемой программы, использование блоков
Добавлено: 20.01.2018{, 13:50}
pan
Sancho писал(а): ↑20.01.2018{, 13:40}
Если мы уберём в полученном коде "лишние", промежуточные переменные, которые всегда возникают при использовании ПБ
этот вопрос помню поднимался еще на старом форуме. и вроде предлагалось типа сделать доступ к переменным в блоках.
а особенно когда блок с кучей булевых входов выходов (которые один фиг занимают по 1 байту)
если бы эти "плюшки" реализовать совместно с ускорением, получился бы не хилый прирост производительности и оптимизации.
Отправлено спустя 1 минуту 46 секунд:
судя по скрину эта библиотека чуть больше жрет оперативы
Оптимизация создаваемой программы, использование блоков
Добавлено: 20.01.2018{, 14:17}
Sancho
pan писал(а): ↑20.01.2018{, 13:52}
этот вопрос помню поднимался еще на старом форуме. и вроде предлагалось типа сделать доступ к переменным в блоках.
а особенно когда блок с кучей булевых входов выходов (которые один фиг занимают по 1 байту)
если бы эти "плюшки" реализовать совместно с ускорением, получился бы не хилый прирост производительности и оптимизации.
Я помню эту тему. Но есть один очень не понятный момент, из-за которого всё остановилось, как мне кажется: если сделать привязку в блоке к переменной проекта, то при изменении её имени, или каких других манипуляциях, что получим? Очень не простой вопрос.
Проще подучится в С++ и править полученный код ( в своей любимой программе), самообразование опять таки.
Отправлено спустя 1 час 22 минуты 25 секунд:
Сделал новый тест, с четырьмя входами и четырьмя выходами.
Тоже генератор с ООС. Прёт на генераторы меня сегодня. Временно.
Насчёт размера оперативки - жрёт немного.
А вот памяти проги, а скорость!
Так-же, заметно невооружённым взглядом, все эти промежуточные пере-присвоения значений здорово добавляют веса и тормозов.
Оптимизация создаваемой программы, использование блоков
Добавлено: 20.01.2018{, 16:26}
pan
Sancho писал(а): ↑20.01.2018{, 15:40}
Очень не простой вопрос.
ну почему же. например в блоке поставить галку типа "глобальная переменная"
а в штатные блоки добавить такой блок "глобальной переменной" и в нем выбирать по типу как "значение пункта меню"
тоесть кликаем, выбираем блок, далее "расшаренную" переменную. а компилятор флпрога будет знать какой индекс он присвоит переменной,
такой же будет и у той которую мы используем отдельно. надеюсь мысль донёс.
Sancho писал(а): ↑20.01.2018{, 15:40}
все эти промежуточные пере-присвоения значений здорово добавляют веса и тормозов.
по поводу веса это понятно. не ожиданно что операции присвоения значений оказались тоже не так уж шустрыми.
в общем есть над чем работать
Оптимизация создаваемой программы, использование блоков
Добавлено: 20.01.2018{, 16:36}
Sancho
pan писал(а): ↑20.01.2018{, 16:26}
надеюсь мысль донёс.
Я это прекрасно понимаю. Но это всего лишь переменная. А если на вход блока подаётся результат с цепочки вычислений, то компилятор должен будет корректно вставить всю эту "гирлянду" на место переменной. А если она(переменная) в блоке используется несколько раз? Вопрос, конечно, интересный...
Оптимизация создаваемой программы, использование блоков
Добавлено: 20.01.2018{, 16:41}
pan
не не. гирлянды из кода не нужны. я именно про реальные переменные в блоке. что б их можно было использовать. они и так уже являются промежуточными. а пока приходится захламлять переприсвоениями.
Оптимизация создаваемой программы, использование блоков
Добавлено: 20.01.2018{, 16:50}
Sancho
pan писал(а): ↑20.01.2018{, 16:41}
я именно про реальные переменные в блоке. что б их можно было использовать. они и так уже являются промежуточными. а пока приходится захламлять переприсвоениями.
В таком случае - да! Ждёмс.
А пока
Sancho писал(а): ↑20.01.2018{, 15:40}
подучится в С++ и править полученный код ( в своей любимой программе), самообразование опять таки
Не по теме
У меня заканчивается смена и начинается {пя} суббоТНИЦА. Время крепких напитков и танков. До связи!
Оптимизация создаваемой программы, использование блоков
Добавлено: 23.01.2018{, 15:54}
pan
после ваших испытаний, посмотрев на цифры, офигел сколько времени занимают операции присвоения значений.
теперь в пользовательских блоках (и по возможности в остальной программе) стараюсь использовать операторы сравнения,
дабы не писать в каждом цикле одно и тоже значение в переменную.
хотя не известно сколько времени занимает сравнение....
Оптимизация создаваемой программы, использование блоков
Добавлено: 23.01.2018{, 16:00}
Sancho
pan писал(а): ↑23.01.2018{, 15:54}
хотя не известно сколько времени занимает сравнение....
Проведу эксперименты...
Отправлено спустя 1 час 5 минут 11 секунд:
Алексей, ерунда какая-то у меня получается
Взял нанку, подключил, 636 кгц, старая заливка. ок. поменял if во вторых строках на else - 122.38 всего.
Ладно, конец дня, косячу наверно, заливаю обратно старый, как я думаю - 218,10 всего. Где 636,55?????????
Короче, вопрос для меня - где и как я смог нагенерить 636 открыт. Макетка не трогалась, остальное тоже, комп не выключался вообще...
Тесты продолжаются....
Код: Выделить всё
#include "CyberLib.h"
void setup()
{
D2_In;
D2_High;
D3_In;
D3_High;
D4_In;
D4_High;
D5_In;
D5_High;
D10_Out;
D10_Low;
D11_Out;
D11_Low;
D12_Out;
D12_Low;
D13_Out;
D13_Low;
}
void loop()
{
if ( D2_Read ) {D10_High;}
if ( !D2_Read ) {D10_Low;}
if ( D3_Read ) {D11_High;}
if ( !D3_Read ) {D11_Low;}
if ( D4_Read ) {D12_High;}
if ( !D4_Read ) { D12_Low;}
// инверсия
if ( !D5_Read ) {D13_High;}
if ( D5_Read ) {D13_Low;}
/*
if (D2_Read) D10_High;
else D10_Low;
if (D3_Read) D11_High;
else D11_Low;
if (D4_Read) D12_High;
else D12_Low;
// инверсия
if (!D5_Read ) D13_High;
else D13_Low;
*/
}
Оптимизация создаваемой программы, использование блоков
Добавлено: 23.01.2018{, 19:12}
pan
интересует разница скорости такого кода
и такого
Код: Выделить всё
D12_High;
if(var1){var1=0;}
D12_Low;
if(var2){var2=0;}
тоесть разницу между присвоением значения переменной и проверкой условия при котором присвоение не выполняется
Оптимизация создаваемой программы, использование блоков
Добавлено: 24.01.2018{, 17:51}
Sancho
Пока коротко
Код: Выделить всё
#include "CyberLib.h"
/*
D12_High;
D12_Low;
от начала 1 до начала 0 125ns, от 0 до 1 - 375 ns(это время не менялось далее), частота 2 МГц
Воемя основного цикла много меньше отработки loop, var1,2 - bool
D12_High; // начало появления 1
var1=0;
var2=0;
D12_Low; // до начала спада к 0
При var bool 375 ns.(ещё отминусовать 125, далеее также)
При var int 625 ns
D12_High;
if(var1){var1=0;}
if(var2){var2=0;}
D12_Low;
bool 750ns.
int 1000ns.
D12_High;
if(!var1){var1=1;}
if(var1){var1=0;}
D12_Low;
Инверсия в цикле при bool 800ns
Инверсия в цикле при int 1360ns
D12_High;
if(!var1){var1=1;var2=0;}
if(var1){var1=0; var2=1;}
D12_Low;
Инверсия в цикле, +var2, при bool 1250ns
Инверсия в цикле, +var2, при int 2000ns
D12_High;
value1=analogRead(2);
D12_Low;
Чтение аналогового входа с присваиванием 112µs
D12_High;
value1=A2_Read;
D12_Low;
Чтение быстрого аналогового входа с присваиванием 64µs!!!
*/
bool var1;
bool var2;
void setup()
{
D12_Out;
D12_Low;
}
void loop()
{
D12_High;
if(var1){var1=false;}
if(var2){var2=false;}
D12_Low;
}
Оптимизация создаваемой программы, использование блоков
Добавлено: 25.01.2018{, 09:24}
Sancho
Обновлён
блок пользователя - небольшие изменения и добавлены быстрые аналоговые входы.
D12_High;
value1=analogRead(2);
D12_Low;
Чтение 1-го аналогового входа с присваиванием 112µs!!! два - 224µs
D12_High;
value1=A2_Read;
D12_Low;
Чтение быстрого аналогового входа с присваиванием 64µs!!! два 136µs
После этого все логические операции в программе становятся ВООБЩЕ малозначимыми по времени выполнения!
Отправлено спустя 1 час 41 минуту 35 секунд:
Упаковка битов в байт
Код: Выделить всё
1-й вариант 8бит в байт с условным сложением
D12_High;
temp_80800547_1=0;
if (b0_80800547_1) {temp_80800547_1+=1;}
if (b1_80800547_1) {temp_80800547_1+=2;}
if (b2_80800547_1) {temp_80800547_1+=4;}
if (b3_80800547_1) {temp_80800547_1+=8;}
if (b4_80800547_1) {temp_80800547_1+=16;}
if (b5_80800547_1) {temp_80800547_1+=32;}
if (b6_80800547_1) {temp_80800547_1+=64;}
if (b7_80800547_1) {temp_80800547_1+=128;}
D12_Low;
2-й вариант с поштучной записью битов
D12_High;
Q_229206310_1=0;
bitWrite(Q_229206310_1, (0), (b0_229206310_1));
bitWrite(Q_229206310_1, (1), (b1_229206310_1));
bitWrite(Q_229206310_1, (2), (b2_229206310_1));
bitWrite(Q_229206310_1, (3), (b3_229206310_1));
bitWrite(Q_229206310_1, (4), (b4_229206310_1));
bitWrite(Q_229206310_1, (5), (b5_229206310_1));
bitWrite(Q_229206310_1, (6), (b6_229206310_1));
bitWrite(Q_229206310_1, (7), (b7_229206310_1));
D12_Low;
8 бит в байт 250ns минус 125 итого на упаковку 125ns, результаты одинаковы по времени и размеру в памяти.
Отправлено спустя 5 часов 34 минуты 3 секунды:
Работа со строками.
Это нечто. По времени в цикле.
строка
_Strochka = (String(10, DEC)) + (String("test_1")) + (String("Test_2"));
выполняется 260µs!!!
А если добавить _Strochka = _Strochka +_Strochka; то уже 320.
Вывод для себя я уже давно сделал - строки и индикацию делать на отдельной плате, вызываемой по необходимости. Подтвердилось.
Ну не смотрю постоянно я на дисплей - зачем он будет кушать ресурсы?
Оптимизация создаваемой программы, использование блоков
Добавлено: 25.01.2018{, 16:56}
pan
Sancho писал(а): ↑25.01.2018{, 16:39}
делать на отдельной плате, вызываемой по необходимости
я когда то предлагал сделать возможность вызова обработки плат как функции. чето не прижилось
Оптимизация создаваемой программы, использование блоков
Добавлено: 25.01.2018{, 17:40}
Sancho
Теперь о шине I2C.
Не буду говорить о быстроте или тормознутости. Мне нравится. Куча переферии, всего два пина, простота.
Теперь тесты:
Код: Выделить всё
D12_High;
Wire.requestFrom((int) 0x57,4);
if (Wire.available()) byte_out_1 = Wire.read();
if (Wire.available()) byte_out_2 = Wire.read();
if (Wire.available()) byte_out_3 = Wire.read();
if (Wire.available()) byte_out_4 = Wire.read();
D12_Low;
Простое чтение четырёх байт с присвоениями 514µs.
Ускорив до 400кГц, а по умолчанию 100, получил 167µs, так как время присвоения остались константами.
Код: Выделить всё
D12_High;
Wire.beginTransmission((int) 0x57);
Wire.write((int)( 321 >> 8));
Wire.write((int)( 321 & 0xFF));
Wire.endTransmission();
Wire.requestFrom((int) 0x57,4);
if (Wire.available()) byte_out_1 = Wire.read();
if (Wire.available()) byte_out_2 = Wire.read();
if (Wire.available()) byte_out_3 = Wire.read();
if (Wire.available()) byte_out_4 = Wire.read();
D12_Low;
При произвольном чтении с любого места с присвоениями при 100кГц получено 844µs, при 400- 274µs.
На очереди - дисплей по I2C... Завтра.
Оптимизация создаваемой программы, использование блоков
Добавлено: 25.01.2018{, 19:59}
pan
seri0shka писал(а): ↑25.01.2018{, 19:51}
Вы имеете ввиду чтобы блоки, находящиеся на конкретной плате, работали только при каком- то условии?
это и так уже есть давно.
я имел ввиду "внеочередной" вызов платы с блоками для обработки нужного алгоритма. как функцию в скетче.
Отправлено спустя 1 минуту 15 секунд:
Сергей автор программы в курсе такой библиотеки. уже говорилось. но придёт ли она в флпрог не известно
Оптимизация создаваемой программы, использование блоков
Добавлено: 25.01.2018{, 20:37}
Sancho
Речь в данной теме пойдёт(а может уже идёт) о правильном и осознанном процессе(анализе необходимого) в составлении всего алгоритма программы, а пока - предисловие, так сказать.
Оптимизация создаваемой программы, использование блоков
Добавлено: 26.01.2018{, 15:52}
Sancho
Итак, дисплей. 20 символов 4 строки.
Переменная для вывода - константа, 1 строка.
Добавлено немного "по краям" опознавание цикла.
Код: Выделить всё
D12_High;
if (_isNeedClearDisp1) {_lcd1.clear(); _isNeedClearDisp1= 0;}
//Плата:1
if (1) {
_dispTempLength1 = ((_gtv1)).length();
if (_disp1oldLength > _dispTempLength1) {_isNeedClearDisp1 = 1;}
_disp1oldLength = _dispTempLength1;
_lcd1.setCursor(0, 0);
_lcd1.print((_gtv1));
}
else {if (_disp1oldLength > 0) {_isNeedClearDisp1 = 1; _disp1oldLength = 0;} }
D12_Low;
I2c
100kHz
10 символов 15,8мс
20 символов 30,5мс
400kHz - те-же результаты!!!
Прямое подключение, 6 пинов
10 символов 3,16мс
20 символов 6,01мс
Пошёл смотреть библиотеки...
Оптимизация создаваемой программы, использование блоков
Добавлено: 26.01.2018{, 19:09}
Nikan
.
Оптимизация создаваемой программы, использование блоков
Добавлено: 26.01.2018{, 19:13}
Sancho
Nikan писал(а): ↑26.01.2018{, 19:09}
Sancho писал(а): ↑26.01.2018{, 15:52}
I2c
100kHz
10 символов 15,8мс
20 символов 30,5мс
400kHz - те-же результаты!!!
интерфейс дисплея (pcf8574) работает на частоте 100kHz (400 не поддерживается) отсюда и результаты одинаковые
Работает на 400 без проблем при 5 вольтах. Проблема в библиотеке.
Оптимизация создаваемой программы, использование блоков
Добавлено: 26.01.2018{, 19:17}
Nikan
.