Перейти к блогу GetChip.net - блог        JilTE[1] - в разработке     Модификации устройств - модификации

 
Текущее время: 28 мар 2024, 17:11

Часовой пояс: UTC + 3 часа [ Летнее время ]



Начать новую тему Ответить на тему  [ Сообщений: 3 ] 
Автор Сообщение
 Заголовок сообщения: Быстрое вычисление процентов в АВ
СообщениеДобавлено: 04 авг 2019, 20:02 
Не в сети

Зарегистрирован: 12 дек 2017, 23:11
Сообщения: 33
Столкнулся с проблемой нехватки машинного времени при цикличных многоэтажных математических вычислениях. Потребовалось в реал-тайм вычислять "по кругу" проценты от полусотни переменных, которые, разумеется, постоянно изменяются.
Казалось бы, простые действия: значение переменной А нужно умножить на величину процентов В, затем разделить результат умножения на 100, и получишь итоговый результат (в процентах) С.
Но контроллер умеющий аппаратно умножать (какая-нить ATMega), к сожалению, не умеет аппаратно делить...
И в итоге оказалось, что если делить программно, то для одного такого вычисления потребуется более 350 машинных тактов, а это при тактовой частоте камня 3,792 МГц почти 100 микросекунд! Соответственно, для того, чтобы вычислить проценты от 50 переменных, потребуется уже 5 миллисекунд. А все это нужно сделать за 3,5 мс, как того требует ТЗ. И за это время еще требуется опросить датчики, запустить кучу ADC, и дождаться их результаты. Короче, тупик...

Долго ломал голову в поисках решения. И таки нашел! :mrgreen:

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

Так кто нам мешает назвать одним процентом не 1/100 часть от целого, а допустим, 1/128 часть от того же самого целого? Ведь тогда описанная выше процедура вычисления новых "процентов" не потребует длительного программного деления, а сведется к восьмикратному, но быстрому аппаратному сдвигу результата умножения вправо (деление на 128). Впрочем, можно получить искомый результат еще быстрее. Достаточно результат умножения один раз сдвинуть влево (умножить еще на 2), и просто отбросить младший байт двух-байтного результата!
Замечу: этот метод применим только для одно-байтных исходных чисел, т.е. оба множителя не должны быть больше, чем 255 (в десятичной системе). Тогда результат умножения вполне себе поместится всего в двух байтах.

Я в секции распределения РОН задал такую переменную Result - r0:Word.

Новый точечный рисунок.jpg
Новый точечный рисунок.jpg [ 9.46 КБ | Просмотров: 5965 ]


В итоге конечный результат вычисления новых "процентов" автоматически оказывается в регистре r1, сам программный код занимает не пол-страницы Алгоритм Буилдера, а всего 4 строки, две из которых предназначены для ввода множителей (исходное значение и требуемые проценты), а время одного вычисления сокращается с трехсот пятидесяти машинных тактов до всего лишь шести машинных тактов, или почти в 600 раз!

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


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Быстрое вычисление процентов в АВ
СообщениеДобавлено: 04 авг 2019, 22:21 
Не в сети
Администратор
Аватара пользователя

Зарегистрирован: 15 май 2011, 23:00
Сообщения: 1904
Отлично!


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения: Re: Быстрое вычисление процентов в АВ
СообщениеДобавлено: 05 авг 2019, 08:46 
Не в сети

Зарегистрирован: 12 дек 2017, 23:11
Сообщения: 33
В большинстве случаев, связанных с циклическими вычислениями процентов, бывает достаточно точности ~2% (например, при ШИМ-регулировке положения вала серво-механизмов). Тогда мой код можно сократить еще на одну строку (убрать: <<Result), при этом величина одного условного процента увеличится до 1/64 от целого исходного, но и этого вполне достаточно для того, чтобы движение вала серво-машинки было практически плавным (без заметных рывков и подергиваний).
Да и задавать такие "64-ичные проценты" будет проще, чем, допустим, отщелкивать энкодером 128 импульсов при необходимости оставить исходную величину без изменений.

По моему глубокому убеждению, можно оптимизировать вычисление практически любой задачи, результат которой должен иметь конечную точность.
Допустим, много-много лет назад, когда я только начал осваивать программирование на ассемблере (на аппаратном ассемблере, про АБ я тогда еще и не знал. А языки высокого уровня так и не освоил до сих пор. :mrgreen: ), мне потребовалось сделать генератор периодических сигналов произвольной формы (что-то типа функционального генератора, выдающего синус, пилу, треугольник, меандр и т.д.).
И все это требовалось сделать на Tiny11, или Tiny12, сейчас уже и не вспомню. Естественно, первый шаг был в сторону чтения табличных значений, записанных в EEPROM или во Flash. Разумеется, эту задачу стандартным методом решить не удалось, у камушка не хватало мозгов...
И тогда я впервые применил метод линейно-кусочной аппроксимации, с помощью которого можно сгенерировать практически любую форму сигнала, а объем табличных данных при этом сократится в разы (а иногда и в десятки раз) - в каждом байте памяти можно хранить данные как минимум о двух последовательных приращениях сигнала. Так, для того, чтобы сгенерировать синус с 64-битным разрешением (с любой частотой и амплитудой), потребуется всего лишь пара десятков адресов памяти, а для генерации треугольного или пилообразного сигнала потребуется всего 1 ячейка памяти!

Я думаю, у многих форумчан есть подобные находки. Было бы не плохо собрать их в отдельную библиотеку, да и вообще, как говориться, нужно чаще ОБЩАТЬСЯ, а не сидеть каждому в своей норе, ковыряясь в кучке заплесневелых АВР-ок. :mrgreen:


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

Часовой пояс: UTC + 3 часа [ Летнее время ]


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

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


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

Найти:
Перейти:  
cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
Русская поддержка phpBB