Еще раз про оптимизацию кода.

RxMaxx
Offline
Зарегистрирован: 10.04.2020

Есть стандартная проблема: написанный код не помещается в память МК. В моем случае используется Arduino Nano со стандартными 32кБ памяти на борту. Заменить ее на что-то более вместительное нет физической возможности, устройство уже собрано и переделывать его под новое железо дорогого стоит. Под все мои хотелки, по грубой оценке, памяти нужно раза в 1,5-2 больше. В природе, конечно, уже есть Arduino Nano Every, которая, судя по всему, могла бы стать выходом из положения (при условии ее полной электрической совместимости с обычной Nano), но во-первых китайцы ее еще не успели клонировать, а покупать оригинал не сильно хочется, и во-вторых эта плата еще не переболела детскими болезнями: ее пока чаще ругают чем хвалят. Да и 48кБ это не сильно больше.

Пытаюсь подойти со стороны оптимизации кода... раньше же и с куда меньшими мощностями как-то в космос летали. Свой код я уже утоптал практически до предела своей компетенции, как еще меньше сделать пока не знаю, но вот большую часть объема у меня съедают чужие внешние библиотеки. Копать каждую из них у меня нет особого желания (хотя минимум одну уже пришлось ручками править, т.к. там были ошибки). Но возникла такая идея: а что, если выдернуть из них только нужные мне функции и оптимизировать уже только их под мои конкретные задачи?

Отсюда вопрос: можно ли как-то увидеть, какую часть кода компилятор в итоге оставляет? Если я правильно понимаю, то при компиляции отбрасываются все лишние функции и переменные, которые, даже если они были объявлены в коде, нигде не используются. Можно ли как-то выдернуть этот полуфабрикат в человеко-читаемом виде для дальнейшего анализа? Покопавшись во временных файлах, которые генерит компилятор, лучшее, что я нашел, это файл, с моим кодом, где заменены все #define’ы и  #if#endif’ы, но оставлен прочий «мусор».  Можно ли как-то все таки увидеть собранный в одном месте, очищенный, но неоткомпилированный код?

 

rkit
Offline
Зарегистрирован: 23.11.2016

Нет. И поменять мк гораздо дешевле

RxMaxx
Offline
Зарегистрирован: 10.04.2020

Дешевле чем что?

b707
Offline
Зарегистрирован: 26.05.2017

RxMaxx пишет:

большую часть объема у меня съедают чужие внешние библиотеки. Копать каждую из них у меня нет особого желания (хотя минимум одну уже пришлось ручками править, т.к. там были ошибки). Но возникла такая идея: а что, если выдернуть из них только нужные мне функции и оптимизировать уже только их под мои конкретные задачи?

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

 

А вообще, если у вас не хвтает ресурсов контроллера не чуть-чуть - а в 1.5 - 2 раза - то тут только два варианта. Либо вы изначально выбрали неверный МК. либо очень неэффективно пишете код... Увы. других вариантов нет.

В качестве саморекламы могу сказать. что у меня обычно обратная ситуация - выбранный МК обычно превышает потребности кода в 2-3 раза. После опробования на Нано зачастую в конечное устройство ставлю Атмегу168, 88 или даже тини

Но правда надо отметить, что у меня ни в одном устройстве нет интерфейса управления - всяких там меню, экранчиков. энкодеров -  обычно предпочитаю создавать автономные девайсы. не нуждающиеся во вмешательстве человека :)

b707
Offline
Зарегистрирован: 26.05.2017

RxMaxx пишет:

Дешевле чем что?

чем тратить время на переписывание библиотек

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

У gcc есть опция -E, почитайте про неё. Включите в IDE вывод всех сообщений компилятора. И, по идее, куда-то обработанный препроцессором код должон промежуточно складываться, во временную папку.

Короче, надо пробовать. Сейчас не с рабочего компа, поэтому более предметно - не могу подсказать. Но Arduino IDE запускает тот же GCC, и передаёт ему параметры командной строки. В настроечных файлах это указано, возможно, там уже есть опция -E. Т.е. получить промежуточный выхлоп - вполне реально, я так натравливал на нужные файлы батник, чтобы поcмотреть, чего там по ассемблеру получается:

"%ProgramFiles%\Arduino\hardware\tools\avr\bin\avr-objdump.exe" -S -h -Tdata %1 > %1%.txt

На *.o или *.elf-файл натравливается, и - всё. С препроцессором, думаю, подобную петрушку тоже можно совершить.

Но что-то мне подсказывает, что не сильно это и поможет - какой прок от файла, прошедшего через препроцессор? Что вы там планируете увидеть? Кмк - для начала гооораздо проще почитать документацию к используемым библиотекам, на предмет настроек тех же директив условной компиляции. Например, UTFT позволяет выключить поддержку некоторых контроллеров, что немного ужимает её код на выхлопе с препроцессора. И всё это описано в документации ;)

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

b707 пишет:

Но правда надо отметить, что у меня ни в одном устройстве нет интерфейса управления - всяких там меню, экранчиков. энкодеров -  обычно предпочитаю создавать автономные девайсы. не нуждающиеся во вмешательстве человека :)

Ну вот как только пересядешь на использование цветных TFT, да на необходимость конфигурировать прошивку посредством софта на компе, да чтоб всё это было с фейерверками и завитушками (юзер нынче избалованный, млять) - вот тогда и увидишь, что 90% рабочего времени и чуть меньше (но не сильно) ресурсов МК - тратятся на всю эту невообразимую хрень :) 

b707
Offline
Зарегистрирован: 26.05.2017

DIYMan пишет:

Ну вот как только пересядешь на использование цветных TFT, да на необходимость конфигурировать прошивку посредством софта на компе, да чтоб всё это было с фейерверками и завитушками (юзер нынче избалованный, млять) - вот тогда и увидишь, что 90% рабочего времени и чуть меньше (но не сильно) ресурсов МК - тратятся на всю эту невообразимую хрень :) 

ты знаешь, я это понял уже 20 лет назад, когда первый раз полез писать UI под винду :)

"Поэтому я и не женюсь" (с) - то есть не работаю с интерфейсами... и теми кто их заказывает :)

DetSimen
DetSimen аватар
Offline
Зарегистрирован: 25.01.2017

RxMaxx, напиши мне завтра на почту. elf-basic@yandex.ru

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

b707 пишет:

"Поэтому я и не женюсь" (с) - то есть не работаю с интерфейсами... и теми кто их заказывает :)

Ээх, везуха... А у мну наоборот - всю жизнь с ними бок о бок.

nik182
Offline
Зарегистрирован: 04.05.2015

Есть nucleo на stm32 сделанная по ногам точно под нану. Со всеми аналогичными выводами. Памяти море. Таймеров и прочей периферии море, аддон ардуиновский, если без прямого обращения к регистрам, почти всё нанино ест.  

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

Assembler должен помочь с оптимизацией.

RxMaxx
Offline
Зарегистрирован: 10.04.2020

DIYMan пишет:
какой прок от файла, прошедшего через препроцессор? Что вы там планируете увидеть? Кмк - для начала гооораздо проще почитать документацию к используемым библиотекам, на предмет настроек тех же директив условной компиляции.

Документация многих библиотек оставляет желать лучшего. Увидеть я планирую именно тот код, который пойдет компилироваться, тем самым ограничить себе поле деятельности. Потом, к примеру, в библиотекe одна функция будет вызывать кучу других, в документации об этом явно сказано вряд ли будет, а полностью проследить логику работы библиотеки довольно сложно. А когда у меня перед глазами будет только тот код, который реально нежен, мне уже проще будет в нем разобраться и что-то подсократить или вовсе переделать. 

DIYMan пишет:

На *.o или *.elf-файл натравливается, и - всё. С препроцессором, думаю, подобную петрушку тоже можно совершить.

*.o и *.elf-файлы я и сейчас вижу во временных файлах, но мне это ничего не дает, нужен все-таки читабельный код, даже ассемблер для меня перебор.

RxMaxx
Offline
Зарегистрирован: 10.04.2020

nik182 пишет:

Есть nucleo на stm32 сделанная по ногам точно под нану. Со всеми аналогичными выводами.

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

RxMaxx
Offline
Зарегистрирован: 10.04.2020

Komandir пишет:

Assembler должен помочь с оптимизацией.

Может быть, когда нибудь... не при моем нынешнем уровне знаний.

b707
Offline
Зарегистрирован: 26.05.2017

RxMaxx пишет:

*.o и *.elf-файлы я и сейчас вижу во временных файлах, но мне это ничего не дает, нужен все-таки читабельный код, даже ассемблер для меня перебор.

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

Вы исходники FLProg видели когда-нибудь? - здесь иногда народ выкладывает... это нереальное нагромождение формально правильных конструкций. в который не прослеживается никакой логики...

RxMaxx
Offline
Зарегистрирован: 10.04.2020

b707 пишет:

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

Объясняю, что я хочу увидеть (не знаю бывает ли это в природе). Как я себе представляю, что сначала все файлы программы и библиотеки должны собраться в один общий файл. Т.е. текст библиотеки должен встать вместо #include, но при этом желательно только те части, которые реально используются. Но я плохо представляю на каком этапе происходит очистка от мусора, боюсь что уже на нечитабельном этапе.

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

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

b707
Offline
Зарегистрирован: 26.05.2017

RxMaxx пишет:

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

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

простите, но судя по симптомам - вы свой код пишете как бесконечную простыню? Или не дай бог почти вся программа состоит из огромного ЛУП и небольшой кучки вспомогательных функций?

Тогда первое, что вам может помочь - структурирование кода. Разбивайте код на отдельные процедуры длиной, желательно, не более 50 строк - и обьединяйте их по функциям... (например, всю математику - в отдельный файл) или по используемому железу... или по частям алгоритма программы.

Смысл в том, чтобы вместо "простыни" в 3-5 тыс строк получить 10-20 файлов по 150-300 строк, каждый из которых в разы проще отлаживать и поддерживать в чистоте. Да и так называемое "повторное использование кода"  очень облегчает жизнь. Написав один раз функции работы с кнопками. со сдвиговым регистром или с датчиком температуры м поместив их в отдельный файл - вы в следующем проекте не пишете их заново, а просто копируете файл в каталог скетча и все

RxMaxx
Offline
Зарегистрирован: 10.04.2020

b707 пишет:

простите, но судя по симптомам - вы свой код пишете как бесконечную простыню? Или не дай бог почти вся программа состоит из огромного ЛУП и небольшой кучки вспомогательных функций?

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

b707
Offline
Зарегистрирован: 26.05.2017

RxMaxx пишет:

Не так, код сырой да, много раз переписывался, а потому там накопился мусор в виде лишних переменных и функций, но это не простыня. Коды я видел и писал куда длиннее.

тогда не совсем понятно, что мешает вам свой код почистить, раз вы точно знаете, что эти функции и переменные лишние. Если сомневаетесь - то хотя бы просто закомментируйте и соберите программу без них... все работает? - значит и правда лишние

RxMaxx
Offline
Зарегистрирован: 10.04.2020

b707 пишет:

тогда не совсем понятно, что мешает вам свой код почистить, раз вы точно знаете, что эти функции и переменные лишние. Если сомневаетесь - то хотя бы просто закомментируйте и соберите программу без них... все работает? - значит и правда лишние

Да не в этом дело, в своем коде я ориентируюсь, как это ни странно, да, там есть мусор и неиспользуемые функции которые не могу использовать из-за недостатка памяти...

Но сейчас я хочу разобраться с библиотеками, мне нужно увидеть, что реально из них используется в итоге, вот и ищу способ как бы это увидеть.

 

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

RxMaxx пишет:

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

Код секретный? Имея перед глазами предмет обсуждения - гораздо легче предметнее вести беседу. Выкладывайте код на гитхаб, и дайте ссылку на репозиторий - глядишь, чего дельного и родится из обсуждения.

sadman41
Offline
Зарегистрирован: 19.10.2016

Можно просто на фрагмент(стиль) глянуть чтобы понять - сможете вы его улучшить или нет.

RxMaxx
Offline
Зарегистрирован: 10.04.2020

DIYMan пишет:
Код секретный?

Нет, просто еще очень сырой и некрасивый, и чтоб его понять нужно очень много комментариев писать, когда упрусь, что уже сам не смогу двигаться дальше, придется наверное опубликовать. 

RxMaxx
Offline
Зарегистрирован: 10.04.2020

sadman41 пишет:
Можно просто на фрагмент(стиль) глянуть чтобы понять - сможете вы его улучшить или нет.

Кусок кода? Без кучи комментов, боюсь будет нечитабельно. У меня к примеру вызов функции может выглядeть как-то так:

setCol((i==3)?MODE&15:BC[6-i],true,(i==3)?16:10,2*i+1,2,(i==3)?(119|((BLNK&RZ)<<7)):(i?33025:257|MS<<15),(i==3)?-1:((BC[7]&1<<(6-i))?0:2),FL&1<<(6-i)?51:255,0,i||MS,(i!=3)&&FL&1<<(6-i)?51:255,255);

 

inspiritus
Offline
Зарегистрирован: 17.12.2012

DIYMan пишет:

b707 пишет:

Но правда надо отметить, что у меня ни в одном устройстве нет интерфейса управления - всяких там меню, экранчиков. энкодеров -  обычно предпочитаю создавать автономные девайсы. не нуждающиеся во вмешательстве человека :)

Ну вот как только пересядешь на использование цветных TFT, да на необходимость конфигурировать прошивку посредством софта на компе, да чтоб всё это было с фейерверками и завитушками (юзер нынче избалованный, млять) - вот тогда и увидишь, что 90% рабочего времени и чуть меньше (но не сильно) ресурсов МК - тратятся на всю эту невообразимую хрень :) 

самым эффективным способом конфигурирования/управления программой оказалась командная строка в вэб запросе. Дальше ее парсю, извлекая команды и аргументы и меняю что предписано менять. Быстро дешево неёмко и заказчик принимает, если объяснить , что бантики, финтифлюшки и загогулинки увеличивают стоимость и железа и кода.

типо http://***.***.***.***/&reset_mod=55

Команда сбросить модуль мониторинга на 55м станке отдается агрегатору а он отсылает её в ответе на запрос в обмене с модулем при очередном сеансе.

b707
Offline
Зарегистрирован: 26.05.2017

RxMaxx пишет:

Кусок кода? Без кучи комментов, боюсь будет нечитабельно. У меня к примеру вызов функции может выглядeть как-то так:

setCol((i==3)?MODE&15:BC[6-i],true,(i==3)?16:10,2*i+1,2,(i==3)?(119|((BLNK&RZ)<<7)):(i?33025:257|MS<<15),(i==3)?-1:((BC[7]&1<<(6-i))?0:2),FL&1<<(6-i)?51:255,0,i||MS,(i!=3)&&FL&1<<(6-i)?51:255,255);

 

вы меня конечно извините :)))

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

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

RxMaxx
Offline
Зарегистрирован: 10.04.2020

b707 пишет:
Вам остается только взять старую винтовки и застрелится.

А почему старую? Была б винтовка, я б ей лучшее применение нашел. 

Стиль как раз продиктован необходимостью сильно экономит память. Как бы ужасно это не выглядело, это как раз раз позволило сильно сократить код (как в исходом виде, так и в откомпилированном). Для чужих глаз код не предназначался, сами просили показать... 

Пробелы я при вставке кода сюда убрал...

b707
Offline
Зарегистрирован: 26.05.2017

вы правда думаете, что каждый лишний символ в исходнике - это лишний байт в прошивке? :))) У вас опыт программирования на Си есть? - или это первый проект?

Это как надо себя не уважать. чтобы так писать? - совершенно не удивительно, что вы в этой каше потеряли переменные и функции. И наверно раздули код больше, чем выиграли за счет этого стиля.

Эффективный код - это еще и красивый код.

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

На ASM так не извратиться ...

RxMaxx
Offline
Зарегистрирован: 10.04.2020

b707 пишет:

вы правда думаете, что каждый лишний символ в исходнике - это лишний байт в прошивке? :))) У вас опыт программирования на Си есть? - или это первый проект?

Это как надо себя не уважать. чтобы так писать? - совершенно не удивительно, что вы в этой каше потеряли переменные и функции. И наверно раздули код больше, чем выиграли за счет этого стиля.

Эффективный код - это еще и красивый код.

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

В своем коде я не путаюсь, повторяю еще раз. И вопрос у меня совершенно не касался моего кода. 

Правил мне и на работе хватает, тут я пишу как хочу, не всем жe на BrainFucke отрываться.

b707
Offline
Зарегистрирован: 26.05.2017

RxMaxx пишет:

И вопрос у меня совершенно не касался моего кода.

а чего же он касался? разве не про оптимизацию этого кода вы спрашивали? - так вот, на мой взгляд такой код лучше всего оптимизируется в мусорной корзинке.

 

b707
Offline
Зарегистрирован: 26.05.2017

RxMaxx пишет:

Правил мне и на работе хватает, тут я пишу как хочу, не всем жe на BrainFucke отрываться.

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

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

 

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

Мда, оптимизировать подобный код - такое себе. Налицо, кмк, подмена понятий: созданием совершенно нечитабельного кода - ну никак не подтолкнуть компилятор к тому, чтобы он начал делать результирующий файл меньшего размера. А вот через пару лет в этой простыне попробовать разобраться - алкоголиком можно стать :)

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

inspiritus пишет:

самым эффективным способом конфигурирования/управления программой оказалась командная строка в вэб запросе. Дальше ее парсю, извлекая команды и аргументы и меняю что предписано менять. Быстро дешево неёмко и заказчик принимает, если объяснить , что бантики, финтифлюшки и загогулинки увеличивают стоимость и железа и кода.

типо http://***.***.***.***/&reset_mod=55

Команда сбросить модуль мониторинга на 55м станке отдается агрегатору а он отсылает её в ответе на запрос в обмене с модулем при очередном сеансе.

Частный случай, не более того. Вы думаете, подобный подход не применяется? Ещё как. Но этого - всегда мало. Пока заказчика устраивает - жизнь легка и приятна. Но как только ему надоест вводить ручками (пусть и параметров немного) - вот тут в полный рост встаёт головняк. Благо, сейчас есть ведроид, междумордие на котором пишется довольно-таки бодро, и очень помогает.

Так что самых эффективных способов - не существует, строго говоря ;) 

b707
Offline
Зарегистрирован: 26.05.2017

RxMaxx - посмотрите на проблему вот еще с какой стороны. Судя по тому, что вы планировали все уместить в Нано, а теперь ее очень не хватает - наверно вы для начала планировали относительно простой проект, а потом напихали в него самых разных функций?

 Подумайте о том, что три отдельных инструмента всегда удобнее, чем комбинированный монстр, у которого с одной стороны молоток, с другой - топор - а вместо ручки полотно пилы с острыми зубьями :)

Знаете, какой самый активно обсуждаемый проект в местом разделе ? - генератор частоты Димакса. с кодом всего на полторы странички. А вовсе не навороченные проекты "умных домов", в которые их авторы напихали все, что им пришло в голову и которые были забыты через неделю после публикации.

RxMaxx
Offline
Зарегистрирован: 10.04.2020

b707 пишет:
наверно вы для начала планировали относительно простой проект, а потом напихали в него самых разных функций

Не совсем так, ардуино - это мое хобби, довольно сильно далекое от того, чем я обычно занимаюсь, и тут я делаю все так, как хочу: пишу нечитаемое, впихиваю невпхиуемое. Задача впихнуть как можно больше в том и состоит, что это сложно, заменить железку на более мощную - это слишком просто. Правильнее было бы все на AMSe делать, но порог вхождения великоват, карантин боюсь закончится раньше...

sadman41
Offline
Зарегистрирован: 19.10.2016

Пишите нормально, оптимизатор многое умеет. А вот эти ваши стотыщмильёнов тернарных операторов, которые превращаются в кучу джампов и иного жонглирования регистрами вместо одного человеческого if() {} else {}, обеспечивающий один джамп, сыканомит и progmem space и психическое здоровье. 

RxMaxx
Offline
Зарегистрирован: 10.04.2020

sadman41 пишет:
вместо одного человеческого if() {} else {}

А не выходит там одного человеческого if/else. У меня здесь вызов функции многих переменных, каждая из которых зависит от разных условий. Я могу для каждой переменной отдельно расписать условия через  if/else, в итоге код визуально разрастется очень заметно, но при этом (для меня) не станет более читабельным (для внешних наблюдателей может и станет, но внешние наблюдатели как бы не предполагались), но при этом скомпилированный код будет будет только больше, как раз за счет того, что мне придется еще и лишние переменные заводить. Я тут за каждым байтом скомпилированного кода слежу, и такой вариант вызова функции оказался самым экономичным (из тех что пробовал). 

b707
Offline
Зарегистрирован: 26.05.2017

RxMaxx пишет:

 Я тут за каждым байтом скомпилированного кода слежу, и такой вариант вызова функции оказался самым экономичным (из тех что пробовал). 

очевидно, что эта "экономия каждого байта" все равно не позволит вам впихнуть 48К кода в 32. Так можно подпиливать последние 20 байтов, когда код не влезает чуть чуть в выбранный МК.  А тут вы помаетесь еще с месяц или полгода - а потом все равно возьмете Мегу :)

Проблема в том, что вы же уже привыкнете так писать - отвыкать будет сложно

-NMi-
Offline
Зарегистрирован: 20.08.2018

RxMaxx пишет:

Я тут за каждым байтом скомпилированного кода слежу, и такой вариант вызова функции оказался самым экономичным (из тех что пробовал). 

дабы ишобы нибыть_песд@болом давай-ка  запость раздез твоих вариантофф функций и нормальном и твоём Ызвращенном виде ----- пасмотрим наризультатЪ.

b707
Offline
Зарегистрирован: 26.05.2017

-NMi- пишет:

дабы ишобы нибыть_песд@болом давай-ка  запость раздез твоих вариантофф функций и нормальном и твоём Ызвращенном виде ----- пасмотрим наризультатЪ.

+100 кстати, давайте сравним

Я бы еще посмотрел на окружение этой функции, чтобы понять - какого дьявола ее нужно вызывать с 30 параметрами, да каждое еще с условием. Сдается мне что налицо ошибки проектирования алгоритма

RxMaxx
Offline
Зарегистрирован: 10.04.2020

b707 пишет:

очевидно, что эта "экономия каждого байта" все не позволит вам впихнуть 48К кода в 32. Так что вы помаетесь еще с месяц или полгода - а потом все равно возьмете Мегу :)

Проблема в том, что вы же уже привыкнете так писать - отвыкать будет сложно

Мега не влезет чисто физически. А насчет привычки, вот пример, на чуть более простом вызове этой функции. По "правилам" мне следует писать как-то так:

  byte pos;
  byte sepbl;
  boolean ldot;
  byte BLINK;
  for (byte i = 0; i < N; i++)
  {
    pos = 3 * i + 2;
    sepbl = ROL8(RZ, 4 * i);
    if ((i == 0) && (MS == true))
    {
      ldot = true;
    }
    else
    {
      ldot = false;
    }
    if ((FL & 1 << (2 - i)) == true)
    {
      BLINK = 51;
    }
    else
    {
      BLINK = 255;
    }
    setCol(BC[3 - i], true, 10, pos, 3, 1, 1, sepbl , 0, ldot, BLINK, 255);
  }

Но вместо этого я пишу так:

for (byte i = 0; i < N; i++) 
setCol(BC[3 - i], true, 10, 3 * i + 2, 3, 1, 1, ROL8(RZ, 4 * i) , 0, (i == 0) && MS, FL & 1 << (2 - i) ? 51 : 255, 255);

На выходе имеем одно  и тоже, как по размеру, так и по функционалу. При этом я вызываю эту функцию с различным сочетанием переменных много раз. Какой же мне способ предпочесть, так чтоб сам код был более читаемый?

b707
Offline
Зарегистрирован: 26.05.2017

RxMaxx пишет:

При этом я вызываю эту функцию с различным сочетанием переменных много раз.

Вы сейчас опять будете ругаться, что тут все обсирают, но только функции стольких аргументов, еще и вызываемые с жестко забитыми в коде значениями типа (10, pos, 3, 1, 1, sepbl , 0, ldot, BLINK, 255) - это однозначный признак неумения проектировать программу. В программе должно быть как можно меньше т.н. "hard-coded" констант - и это правило не на пустом месте придумано. Каждая такая константа в коде - это какбы роспись автора в том, что он не осилить рассмотреть закономерность кода, в котором эта константа превратилась бы в вычисляемую переменную .

Что я имею в виду - можно записать вот так

func(1);
func{2);
func(3);
func(4);
...
func(17);

а можно циклом for от 1 до 17 в одну-две строки

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

Чувствую что то мне эта упертость ТС напоминает ...

Нашел - http://arduino.ru/forum/programmirovanie/etyudy-dlya-nachinayushchikh-blink-i-bez-delay-i-bez-millis?page=7#comment-532312

b707
Offline
Зарегистрирован: 26.05.2017

RxMaxx - а вы случаем не участник с ником b612 ?

Очень на вас похож. Тоже приходил сюда и показывал свой своеобразный код. Проблема у него была таже - не хватало места в контроллере. У него код светодиодных часов 6 тыс строк занимал...

Вы с ним интересные феномены

RxMaxx
Offline
Зарегистрирован: 10.04.2020

b707 пишет:
В программе должно быть как можно меньше т.н. "hard-coded" констант

О каких константах речь вообще? Я лишь пример привел, когда часть аргументов не меняется. Я бы мог первый пример расписать, но мне лень. И в чем проблема многих переменных? Ну, вот функция такая, которая очень, часто используется. И вычислить одну переменную из другой либо нельзя либо нерационально.

b707
Offline
Зарегистрирован: 26.05.2017

RxMaxx пишет:

 И в чем проблема многих переменных? Ну, вот функция такая, которая очень, часто используется.

ну хотя бы в том, что вместо 1 функции с 30 переменными обычно эффективнее написать 5 функций с пятью параметрами. Разбивая задачи на меньшие составляющие, у вас будет больше шансов повторно использовать код.

Посмотрите профессиональный софт, те же библиотеки на ГИТхабе - больше пяти параметров как правило имеют только конструкторы классов. Все остальные функции - 2-3 параметра, редко больше.

nik182
Offline
Зарегистрирован: 04.05.2015

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

RxMaxx
Offline
Зарегистрирован: 10.04.2020

b707 пишет:
RxMaxx - а вы случаем не участник с ником b612 ?

Не, не он, я проверил. У меня в отличии от b612 нет привычек обзывать переменные транслитом, выкладывать большие куски кода и описание устройств и материться в комментариях. Может еще различия есть.

RxMaxx
Offline
Зарегистрирован: 10.04.2020

b707 пишет:
вместо 1 функции с 30 переменными обычно эффективнее написать 5 функций с пятью параметрами.
Ну, переменных у меня всего 12, что ближе к 5 чем к 30. Разбить функцию на части не выйдет, точнее я не вижу в этом смысла. Могу вообще отказаться от передаваемых переменных и использовать глобальные, если в этом есть смысл. А, а так, просто примите тот факт, что это функция такая, которой нужны 12 параметров.