Задача написать оптимальный алгоритм преобразования частоты #750237


#0 by D_Pavel
Есть какой-то процессор, например 8086. На входе в порт процессора поступают импульсы с какой-то частотой. Нужно написать оптимальную самое главное по времени расчета, а так же не большую по размеру программу измерения этой частоты, и выдачи из другого порта другой частоты, равной входной частоте помноженной на N, где N - любое число от 0 до 100. Например: N=40.5 На входе 100 Гц На выходе должно быть 4050 Гц. Операцию деления или умножения не предлагать, разумеется.
#0 by D_Pavel
Есть какой-то процессор, например 8086. На входе в порт процессора поступают импульсы с какой-то частотой. Нужно написать оптимальную самое главное по времени расчета, а так же не большую по размеру программу измерения этой частоты, и выдачи из другого порта другой частоты, равной входной частоте помноженной на N, где N - любое число от 0 до 100. Например: N=40.5 На входе 100 Гц На выходе должно быть 4050 Гц. Операцию деления или умножения не предлагать, разумеется.
#1 by kosts
На 1С надо написать?
#2 by SeraFim
N - целое число?)) А циклом суммировать можно?)
#3 by D_Pavel
Хоть на чем, что можно потом скомпилировать в машинные коды. Не целое. Можно хоть циклом, если это будет оптимально.
#4 by Xapac
Функция преобразовательчастоты(N, H)   возврат N*H; КонецФункции; оно?
#5 by Маратыч
Помнится, игрался с умножением сдвигом, есть на просторах Сети даже софтинка, рассчитывающая оптимальный алгоритм умножения сдвигом на константу. Но там, во-первых, работа с целочисленной константой, во-вторых, если констант несколько (100 штук, ага), для каждой нужно свой алгоритм в код вкорячивать.
#6 by ДенисЧ
если нужно - напиши. В чем проблема?
#7 by Lama12
Почему умножение не предлагать? Я не помню есть ли в ассемблере умножение, но предполагаю что в современных процессорах что-то осталось от мотсопроцессоров 90х годов :)
#8 by ЧеловекДуши
Какова формула расчета? Что за сложность? И в чем оптимальность? Каждый язык программирования требует собственную оптимальность :) ... Чет автор темнит, иль выполнить на Ассемблере простое умножение уже не может? :)
#9 by ЧеловекДуши
На Ассемблере есть все, ведь по сути это самый нижний уровень... ниже только бит-ы :)
#10 by D_Pavel
Оно, только у тебя не вычислено "H" и не понятно что делать с результатом функции.
#11 by D_Pavel
Написал уже. Интересно сможет ли кто-нибудь такой же хитрый маневр придумать, или даже еще лучше.
#12 by D_Pavel
Потому что вариант с умножением сильно отстает по скорости от множества других более оптимальных вариантов решения этой задачи.
#13 by 1Сергей
теперь самый главный вопрос. как запустить 8.3 на 8086?
#14 by D_Pavel
Отличный вопрос. Жаль что он не имеет отношения к данной теме, а то бы обсудили его.
#15 by Feunoir
Да ну? Ещё 486 процессор на своём сопроцессоре умножал вещественные числа одинарной точности за 11 тактов. А уж современные процессоры это вообще за пару тактов делают. Ну попробуй, напиши что-то более быстрое.
#16 by 1Сергей
>>А уж современные процессоры это вообще за пару тактов делают. можно с этого место поподробнее
#17 by ЧеловекДуши
Держи, Оптимизация программ на ассемблере, как раз под 8086
#18 by D_Pavel
Сопроцессора в условии задачи не было.
#19 by D_Pavel
Молодец, , понял суть основной проблемы этой задачи.
#20 by Feunoir
Ну найди процессор без сопроцессора, я на него гляну, ага. Начиная с 486 это неотъемлемая (за исключением 486SX) часть основного процессора.
#21 by rphosts
тупо считаешь кол-во тактов между 2 импульсами на входе(пусть T1). Делишь на свой множитель (Т1/N)... всё, больше входной сигнал не нужен, каждые Т1/N тактов процессора выплёвывать на выход импульс.
#22 by D_Pavel
Ну правильно. Только Т1/N довольно медленная и не оптимальная операция. Нужно что-то более быстрое.
#23 by D_Pavel
8086 например.
#24 by Маратыч
Самое быстрое - зашить в код предварительно рассчитанные результаты всех возможных перемножений %)) Только про оптимальный размер можно забыть.
#25 by rphosts
ну типа она выполняется только 1 раз за всё время. Потом на числа с плавающей точкой просто так не делится...
#26 by Маратыч
Ты не поверишь, до появления MMX-ов до 130 тактов доходило. Именно умножение.
#27 by D_Pavel
Это точно. Проблема в том что множители могут быть как однобайтовые, так и двух-трех байтовые, да и N не целое число, слишком много вариантов получается. Не годится.
#28 by Feunoir
Я не просто верю, я знаю. Впрочем если у ТС чисто академический интерес, то можно и помучиться.
#29 by D_Pavel
Цель - вычислять как можно быстрее. Потому что это не один раз вычисляется, а много раз, так как частота может изменяться. Время вычисления должно укладываться в один период импульса.
#30 by Lama12
F можно граничные условия озвучить? Какова максимальная частота на выходе может быть?
#31 by Lama12
F=А
#32 by D_Pavel
Максимальная частота не ограничена, все упирается в алгоритм. Чем лучше алгоритм, тем более высокую частоту сможет обработать процессор, либо более медленный процессор будет возможно использовать.
#33 by kudlach
Если на выходе частота должна превышать частоту на входе и частота на входе сравнима с частотой процессора, тады ой....  Озвучивай порядок частот.
#34 by Lama12
Не хочется огорчать, но теорема Котельникова говорит что выше чем половина частоты процессора. на выходе не получишь. При условии что лучшие компиляторы дают замедление производительности примерно в 3 раза (по сравнению с аппаратной реализацией), а в среднем 5-10 раз, то при использовании процессора с частотой 3 ГГц, на выходе получишь максимум 500 кГц. Для более высоких частот нужна аппаратная реализация. Стоит ли заморачиваться на оптимизации кода?
#35 by ДенисЧ
теорема Котельникова про процессоры вообще ничего не говорит...
#36 by Lama12
Да ладно? Какая должна быть частота обработки сигнала определенной частоты, что б его можно было восстановить однозначно?
#37 by ДенисЧ
Я могу тебе на счётах или на бумажке оцифровывать сигнал. Процессор тут ни причём. И кстати, не частота обработки, а частота дискретизации.
#38 by Lama12
Про обработку - утрирую. Возможно я не туда применил теорему. Тут, вероятно, более верно будет применить ее в к входящему сигналу. Т.е. для вычисления частоты входящего сигнала нужно иметь частоту устройства производящего дискретизацию, примерно в 2 раза выше входящего сигнала. Так наверно буде правильнее.
#39 by Mikeware
вы совсем забыли теорему Котельникова...
#40 by D_Pavel
Частота сигнала ограничена только скоростью обработки. То есть если имеем процессор с частотой Х ГГц, то чем лучше напишем программу, тем выше частоту на входе и выходе сможем обработать.
#41 by Lama12
Хорошо. Какова должна быть частота процессора, что б "воспринять" сигнал частотой 2 ГГц, да так, что бы в последствии его можно было однозначно восстановить?
#42 by Остап Сулейманович
Аппаратный умножитель всегда сможет выдать частоту кратную опорной.
#43 by Маратыч
А аппаратные умножители с переменной кратностью бывают? Еще и с дробной к тому же.
#44 by Остап Сулейманович
Зависит от аппаратной реализации счетчика. Если достаточно прочитать количество прошедших импульсов раз в секунду - примерно 3 Гц. На первом такте получить показания счетчика. На втором умножить на множитель. На третьем выставить множитель на исходящей стороне.
#45 by Остап Сулейманович
АВМ может все и даже больше.
#46 by Остап Сулейманович
+ Банальный колебательный контур с переменной емкостью (как на старых приемниках).
#47 by Mikeware
во-первых, выше внутрнней частоты процессора ьы ничего не вычислить, а выше тактовой частоты периферии - не выдашь. Во-вторых, в задаче не указано, что делать с формой сигнала. В третьих- не сказано про переходные процессы. В четвёртых, такая задача достаточно просто решается периферией МК - скажем, двумя таймерами. Ну а умножить на 10 сдвигами - не вопрос...
#48 by Lama12
В том то и дело, что как ни крути, упираемся в аппаратную реализацию АЦП и ЦАП.
#49 by Маратыч
Не, я неверно выразился. Оно в форм-факторе микроконтроллера серийно выпускается?
#50 by D_Pavel
Отлично. А какой алгоритм у аппаратного умножителя?
#51 by Lama12
Кстати - да. АВМ лучший вариант в данном случае.
#52 by D_Pavel
Ну есть у тебя два таймера. Как для них задашь параметры? Их нужно вычислить. В том и вопрос!
#53 by Остап Сулейманович
+ "Данный умножитель частоты допускает только шестнадцать ступеней регулировки тактовой частоты. Код, определяющий коэффициент умножения вводится через упрощенный последовательный порт, собранный на сдвиговом регистре D2. В более сложных схемах умножителей частоты вводятся делители между опорным генератором и фазовым компаратором. Это позволяет реализовывать дробные коэффициенты умножения частоты."
#54 by kudlach
Тогда уж, в этой задаче лучше вообще забыть о программировании и вернуться к старым добрым аналоговым аппаратным средствам. Радиотехника ж.
#55 by Mikeware
завязывайте с наркотиками!,©
#56 by D_Pavel
Где же взять этот АВМ, подходящий для задачи?
#57 by Маратыч
О как, а я и не знал. Тады да, лучший вариант - аппаратная реализация.
#58 by D_Pavel
Аналоговые умножители как-то не супер. Нелинейность зависимости входной и выходной частоты присутствует. Цифровой точнее будет.
#59 by Маратыч
Эмм... вот тут, думаю, ты ошибаешься :)
#60 by Mikeware
зачем? STM32 вполне достаточно, даже F0. Эта задача даже не повод рассматривать "взрослые" DSP.
#61 by D_Pavel
Слишком сложно. Давайте ограничимся PIC 12F629 и условиями из .
#62 by D_Pavel
+ В нем даже два уже таймера есть, как ты и писал в
#63 by Mikeware
ну и в чем тогда проблема? Первый таймер в захват, все, что он насчитал - делишь на 10, и в регистр второго... Режимы пиков, правда, я плохо помню- но вроде оба нужных есть...
#64 by Mikeware
На СТМке можно проще - тактируешь  выходной счётчик в 10 раз более высокой частотой, чем входной, и просто перебрасываешь в прерывании рассчитанное первым счетчиком
#65 by Garykom
Это только мне кажется что задача в слегка странная и чисто на проце без "бесконечной памяти" не решается? В общем случае? ЗЫ пришло 1 лям импульсов с частотой 1 Гц, нужно на выход с N = 100, итого выдавать импульсы будем в 100 раз дольше ЗЫ если промежутки между импульсами (частота плавает) разные, то нужен буфер и нехилый
#66 by D_Pavel
>> ну и в чем тогда проблема? Во тв этом: >> что он насчитал - делишь на 10 Делить на 10 долго. Например, мне нужно на каждые 3 входящих такта выдать 2 исходящих. То есть в данном случае N = 0.6667 приблизительно. Долговато деление произойдет.
#67 by D_Pavel
>> тактируешь  выходной счётчик в 10 раз более высокой частотой Это не проще. Откуда взять тактовый сигнал? А если не в 10, а в изменяющееся со временем число раз?
#68 by Гёдза
Делай что-то типа такого: сдвиг + сложение Снижение_стоимости_операций
#69 by Mikeware
Хм. Чойто я в коэффициент  10 впёрся. В условиях- то любой до 100. Ну вот этот коэффициент и загонять в предделитель. А вообще, задача и правда дурная.
#70 by D_Pavel
Аппаратный предделитель там только 2, 4, 8. Не катит.
#71 by Mikeware
делить на 10 - совсем недолго.  3 сдвига, запись, 2 сдвигаа, вычитание. Для пика -вроде циклов 15.  Что касается "за такт"- возьми контроллер с подходящей тактовой...
#72 by D_Pavel
Делитель заранее не известен, иначе бы легко было.
#73 by Mikeware
ну и выкинь это .овно, и возьми нормальный. Не нравится - считай на счетах, тактируй кнопкой. Есть 100500+ способов, но тебе почему-то нужен самый извращенный.
#74 by Mikeware
сделай на FPGA. Пример тебе привели выше. Можешь хоть  на кипарисовом соке.
#75 by D_Pavel
Сделал частный случай для N = 0.6667 Процедура 9 байт, время обработки одного импульса от 6 до 10 тактов.
#76 by D_Pavel
Алгоритм такой: Прерывание сработает либо при входящем скачке снизу вверх, либо сверху вниз. В обработчике прерывания от входящего сигнала: 1. Инвертирую выход через XOR 2. Если выходной сигнал низкого уровня, тогда возврат из прерывания. 3. Инвертирую через XOR значение уровня входного сигнала, при котором сработает прерывание 4. возврат из прерывания. Всего четыре действия! Но на ассемблере эти четыре действия распухают аж до 9 команд, все таки более низкий уровень.
#77 by Rebelx
определись, какая нужна точность. Если количество значащих цифр укладывается в разрядность процессора - умножай целочисленно на 10Е?? и дели опять же целочисленно на нужный коэффициент.
#78 by D_Pavel
По условию задачи нужно ведь оптимальный по скорости алгоритм, а не любой первый попавшийся.
#79 by Rebelx
сколько тактов занимает целочисленное деление и умножение для твоего процессора?
#80 by Rebelx
опять же есть например целочисленные алгоритмы применяемые в машинной графике. В данной задаче наверняка подойтет тот, что рисует прямую - по формуле х = к * у
#81 by D_Pavel
Слишком много, не годится. аналогично, слишком долго.
#82 by Rebelx
слишком много - это сколько?
#83 by D_Pavel
больше чем другими способами можно сделать.
#84 by Кирпич
ты сначала сделай хотя бы медленно, чтобы понять что ты вообще делаешь, а потом уже думай как оптимизировать. а то вакуумного коня тут в ступе толчешь.
#85 by Xapac
ты же написал, что Герцы (H) оно дано на входе. а что делать с результатом, отправлять его на выход. (ваш КЭП) а где он этот выход. ты уж подробно расскажи задачу.
#86 by Кирпич
деление и умножение это вообще не проблема. проблема как выводить эти самые умноженные импульсы. да еще и одновременно со считыванием из другого порта :)
#87 by vde69
Все не читал, на8086 оптимальным будет перехват прерывания таймера, то есть банально нужно изменять максимум счетчика, а генерация бкдет идти автоматом. только нужно иметь в виду, что на старых ОС нельзя изменять порт часов это грозит разрушением диска, точнее менять можнл, но нужно запрещать дисковые лперации
#88 by Kvant1C
А для чего это нужно, если не секрет?
#89 by SUA
умножение еще не предлагали? тем более с фиксированными константами компиляторы оптимизируют сейчас сами поидее
#90 by Garykom
и все это без использования очереди? допустим импульсы всегда одинаковые по длительности (правильные П одной формы) тогда важен только промежуток (интервал) между импульсами на входе берем длину между импульсами (время прошедшее с момента предыдущего) * N и засовываем в очередь на выходе просто берем из очереди, ждем время и выдаем импульс понятно нужны разумные ограничения на величину максимальную и минимальную между импульсами (частоты снизу и сверху) основной цикл работает на выход, и по прерыванию на входящий импульс отрабатывает вход (вычисляет интервал, умножает на N, засовывает в очередь) понятно что будет (может быть точнее) некоторая погрешность на выходе из-за отработки прерывания на входе
#91 by Mikeware
а если скважность - не 2? :-) Брезенхем тут ни при делах...тут гораздо ближе BAM (binary angle modulation). Хотя нужнее паяльник, чтобы вытрясти с ТС ответы на поставленные вопросы.
#92 by vde69
нет, ты не понял.... не нужен ццикл, нужно привязаться к микрухе таймера. для начала  отключани диски,  потом изменяем адрес прерывания на свою программу,  далее изменяем частоту генерация прерывания на нужную.   То есть у тебя будет 2 процедуры привязаные к даум разныи прерываниям, первая этл чтение порта и расчет делителя,  вторая таймер. Все.
#93 by vde69
+ а прогу вешаем в память как резидентную
#94 by Mikeware
в топике ТС говорит о отдельном 8086, не в составе писюке.ниже уже ведёт речь о весьма мелком PICе.  Т.е. ТС сам не знает, чего ему надо. Да, а в стандартном таймере, емнип, три канала, и третьим для генерации можно пользоваться абсолютно невозбранно.
#95 by vde69
писюки сильно разные были, я на них собаку сожрал 20 лет назад. таймеры то-же разные были, в том числе и одноканальные,  трехканалки появились примерно с 286х мы в нии делали на хт хитрые анализаторы профиля (типа электронного измерителя размерм). У меня дома книг по сабжу целая полка была.
#96 by Garykom
да можно и через 2 прерывания, но нафига? если проц не занят больше ничем то лучше в нем гонять цикл корректировки выхода, разные проверки на совпадение времени нужного подачи импульса следующего
#97 by Mikeware
8253 и наш аналог кр580ви53 по жизни были трехканальными. А других просто не было.
#98 by D_Pavel
Кстати, за Брезенхема спасибо, пригодится в другой задаче.
Тэги: Математика и алгоритмы
Ответить:
Комментарии доступны только авторизированным пользователям

В этой группе 1С