Как говорится, любую прошивку можно сделать на байт короче. Так говорили в эпоху 8-биток. Сейчас на 32-битках, наверное, на все 4 байта.
Возился тут как-то с RISC-V. Исследовал особенности архитектуры - доступ к CSR, выравнивание, байтовый и пословный доступ. На включении кварца подумалось, а почему бы на Cortex-M в лице STM32 то же самое не делать? Подумано - сделано. Докладываю результаты.
Берём первый попавшийся STM32 и разными способами включаем кварцевый резонатор. Для этого надо установить один бит в регистре RCC_CR. Большинство (в библиотеках STM скорее всего так же) напишет вот так
Итого: 14 байт - чтение из памяти программ, чтение регистра периферии, логическая операция и запись обратно в регистр периферии.
Хотелось бы оптимальнее. Воспользуемся тем, что мы при включении питания (а по хорошему вообще всегда) знаем полное состояние RCC_CR. И просто запишем это значение с взыдённым битом HSE_ON. Получается так
Те же 14 байт, но теперь это два чтения из памяти программ и запись в регистр периферии. Разменяли чтение регистра периферии и логическую операцию на чтение из памяти программ. Выполняться будет на несколько тактов быстрее.
До сегодняшнего дня у меня в коде так и было и кочевало из контроллера в контроллер. Но ведь можно ещё лучше сделать. Попробуем, сработает ли с байтовым доступом?
И того: 10 байт - загрузка короткой константы в регистр процессора, одно чтение из памяти программ и одна запись в регистр периферии. Сработало. Ещё минус несколько таков и 4 байта кода!
Замечания: 1. Загрузка адреса регистра RCC_CR принадлежит не только операции включения кварца, а всему блоку работы с RCC. Дальше по коду наверняка будет включение PLL и это всё та же байтовая запись в старший байт того же RCC_CR не задевая младших. 2. Не вся периферия поддерживает байтовый доступ. Нужно читать документацию или пробовать.
Ну что ж, поздравляю конечно же. Однако, всю эту прелесть сэкономленных пары-тройки тактов с лихвой обгадит время запуска кварца и выхода его на рабочий режим. И вы обязаны проверять флаг готовности HSE, поскольку если кварц сдох или просто не вышел на рабочий режим, а вы переключаетесь на него, то всей дальнейшей работе придет гитлер-капут.
Ну лично я бы сделал (да иногда и делал) проще - через бит-бандинг (в тем МК, где он есть) - отдельное включение/выключение бита, отдельная проверка состояния бита. Это уж если настолько заэкономиться. Хотя такой экономный подход лучше применять там, где он действительно будет заметен, например при частых вкл/выкл одного бита, например в таймерах, в SPI, еще в чем-то.
Однако, всю эту прелесть сэкономленных пары-тройки тактов с лихвой обгадит время запуска кварца и выхода его на рабочий режим. И вы обязаны проверять флаг готовности HSE, поскольку если кварц сдох или просто не вышел на рабочий режим, а вы переключаетесь на него, то всей дальнейшей работе придет гитлер-капут.
Как это вообще связано с командой включения кварца? Сэкономленные такты и байты куда-то пропадут? Нет.
Хотя такой экономный подход лучше применять там, где он действительно будет заметен, например при частых вкл/выкл одного бита, например в таймерах, в SPI, еще в чем-то.
А если подумать? Работа с периферией обычно не ограничивается одним регистром. В любом случае загружается базовый адрес периферийного модуля и от него идёт относительная адресация к разным регистрам. Ради одного бита загружать ещё один адрес? Антиэкономия какая-то.
А если подумать? Сэкономленные три такта растворятся в вариациях времени запуска кварца. Вы просто не в том месте начали оптимизировать. Хотя конечно хорошо, что вы наконец-то открыли для себя побайтовый доступ, это вам пригодится в будущем. Ну и не стоит натягивать универсальный шаблон поведения на разные микроконтроллеры. Надо быть гибким и мыслить всегда в конкретной плоскости, а не философствовать о сферических конях в вакууме. Успешный программист - он всегда гибкий и применяющий конкретные методы из своего арсенала в различных задачах. А тот, кто пытается, образно говоря, натянуть одинаковые трусы на все существующие жопы мира, он потратит кучу времени и создаст нечто хреново-безобразное и кривое.
А тот, кто пытается, образно говоря, натянуть одинаковые трусы на все существующие жопы мира, он потратит кучу времени и создаст нечто хреново-безобразное и кривое.
А если подумать получше? Время запуска кварца нестабильно, зависит от внешней среды, а она изменичива. Время запуска кварца значительно превышает те пару-тройку сэкономленных тактов, а разброс времени запуска и вовсе съест экономию чисто из-за разброса. Вы бы знали это, если бы больше практиковались. Зря вы обижаетесь, зря! Я вам добра желаю и подсказываю, что где и как работает. Оптимизировать такты нужно там, где постоянно дергается один бит в цикле. Например, тот же самый SPI в полудуплексном режиме, когда идет смена направления передачи. Многие устройства работают по полудуплексному SPI, и чтобы прочитать регистр из устройства, нужно сначала передать в него адрес регистра, затем перевести интерфейс на прием и принимать байты.
Команда N3 полностью "съедает" все такты (не только сэкономленные) команды N2, но не команды N1. И никак не влияет на сэкономленные байты обеих команд.
А вы молодец, что шуршите байтиками головного мозга Правда, еще не достаточно интенсивно. Я ж говорю, если бы в больше практиковались, то понимали бы, что время запуска кварца намного превышает время прохода нескольких инструкций, и во-вторых и это самое главное тут - оно ИЗМЕНЧИВО! Понимаете, оно непостоянно, и мера его непостоянности превышает количество сэкономленных тактов.
Вот на практике, по результатам 4-х измерений: Как видно, время запуска кварца в среднем чуть больше 300 мкс (более 2400 тактов при HSI 8 МГц), а вариации в четырех попытках даже в одних и тех же условиях составляют 7 мкс или 56 тактов при HSI 8 МГц. Если частота HSI будет 16 МГц, то разница будет еще более заметна. А сколько сэкономили вы? Пусть даже 20 тактов. Всё равно они отбиваются вариациями времени запуска, особо заметными при изменении температуры и питания. И вы сами можете в этом убедиться, конечно если у вас вообще есть осциллограф или лог.анализатор, и вообще есть микроконтроллер в железе Ну а когда дорастете до запуска "часового" LSE, поразитесь еще больше - время запуска и его вариации измеряются аж в секундах! Вот так то! Это, брат, не теория, это практика, суровая и беспощадная Вот только ради бога не обижайтесь, это же реалии, а на них нельзя обижаться. А вот вам еще тема для "подумать, поковыряться": зачем сделано прерывание по готовности HSE? Показанное время его запуска и кол-во тактов ожидания как бы проясняют и намекают на ответ В общем, пожелание - в наступающем году купите лог.анализатор и отладочную плату и потыкайте всё это на практике. Ну, с новым годом, удачи!
Поразительно. Столько энергии тратить чтобы доказать, что бесплатное уменьшение размера прошивки и увеличение скорости исполнения команды это плохо. Даже какую-то диаграмму, совершенно не относящуюся к делу, снял зачем-то. Она показвает время исполнения команды? Нет. Может размер прошивки на ней видно? Тоже нет. Показывает, что у дяди на работе есть дешёвенький осциллограф и неумение поставить эксперимент. А все эти рассуждения о наличии у меня приборов, отладочных плат, автомобилей, яхт и т.д. это банальное хамство, которым прикрывается отсутствие аргументов. Остаётся только сожалеть, что модератор покрывает это.
PS: Человек мало мальски разбирающийся в вопросе спросил бы: а какое ядро процессора, есть ли там конвейер, кэши, предвыборка, предсказание переходов и т.д. А "форумный эксперд" будет время запуска кварца измерять зачем-то...
Долго ж вы думали, как ответить. Вчера зашли, прочитали, задумались и ушли, долго примеряли то да сё, пытаясь хоть чето вкурить, сегодня поняли, что ничерта не врубились и за неимением адекватных аргументов, решили что лучше будет просто нахамить, чем признаться в своей неправоте. Даже когда наглядно показал вам время запуска кварца, вы все ещё ничего не поняли. Это говорит о том, что вы совершенно оторваны от практики и не способны осознать физические явления. Ну и судя по тому, что не умеете прочесть и понять цифры, то ни осциллом, ни анализатором вы не пользовались. Иначе бы поняли! Никакие кэши и предсказания переходов не помогут, когда время ФИЗИЧЕСКОГО запуска кварца более 2 тыс тактов. Вы это не можете осознать просто потому, что не пробовали вживую в железе
И прекращайте хамить и ябидничать уже! С вами тут цацкаются, а вы ведёте себя как хамло какое-то форумное. Некрасиво это, некрасиво. Ели вы считаете, что задето ваше непогрешимое ЧСВ, ну что ж поделать, напишите все ваши претензии и недовольства на бумажке и сходите с ней в туалэт типа сортир ничем другим никто вашему безумно ущемленному ЧСВ не поможет
Как видно, время запуска кварца в среднем чуть больше 300 мкс (более 2400 тактов при HSI 8 МГц), а вариации в четырех попытках даже в одних и тех же условиях составляют 7 мкс или 56 тактов при HSI 8 МГц.
Кстати , за 2400 тактов можно успеть настроить 20 ног самым топорным способом. Ну или все сразу загрузкой массива.
Оптимизацией приходится заниматься когда прижмёт, ну или когда слишком много свободного времени. Я для этих целей использую https://godbolt.org/z/7hro4zPPz , там очень удобно в плане быстрого переключения между разными мк и компиляторами. Самый уродливый код получается на старой авр (чисто поржать).
VladislavS - забей на этот бит-бандинг, с ним у тебя будут большие проблемы на старших чипах.
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете добавлять вложения