Перейти к содержанию
    

Самомодифицирующийся код в экосистеме Cortex-M.

Оптимизация по скорости? А то я хотел microPython предложить, для best-in-class супер простой самомодификации кода.

уже предложили. только заметил.

 

По скорости. Ну если у меня оптимизация на таком уровне (генерация маш.кода), то это совсем другой порядок скоростей, чем смогут всякие явы и питоны :laughing:

мда. присоединюсь про другое железо. Явно Allwinner просится

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Тогда я не согласен с названием "самомодифицирующийся", у меня загрузчики тоже загружают разные не то что функции, а целые программы(и да в машинных кодах, разумеется) в зависимости от аргументов.

Попытаюсь объяснить (как я это понял), что подразумевать под "самомодифицирующимся кодом" топикстартер.

 

Не.

 

Не буду. Боюсь всё равно не поймёте

А разжигать холивар не хочу

 

Впрочем, скажу кое-что.

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1. Просчитать все условные флаги.

2. На основании этих флагов сформировать СМК-последовательность инструкций без условных инструкций.

3. Отдать эту последовательность на выполнение.

Простите, а пункты 1 и 2 не требуют тактов разве?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Так тут будет тот же

if()...if()...if()...

Нет, не будет.

 

Простите, а пункты 1 и 2 не требуют тактов разве?

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

while(условие)
{
    if(условие 1)
        инструкция 1;
    if(условие 2)
        инструкция 2;
    if(условие 3)
        инструкция 3;
}

Как видно, будут всегда выполняться инструкции, реализующие условия проверки внутри if(...).

Если применить СМК, и вычислить условия в if(...)-ах до цикла, то в ОЗУ построится, допустим, следующий код (примем, что условия 1 и 3 истинны)

while(условие)
{
    инструкция 1;
    инструкция 3;
}

Или же, если все условия истинны, то

while(условие)
{
    инструкция 1;
    инструкция 2;
    инструкция 3;
}

Или же, если первое условие истинно, то

while(условие)
{
    инструкция 1;
}

Как видно, в любом случае нет больше в цикле инструкций проверки условий в if(...)-ах (а они же ведь по сути Bxx в ассемблерном представлении) (да и куда лучше вовсе не проверять заранее ложные условия по списку), а выполняются только нужные инструкции сразу, как будто условных конструкций и нет. А п. 1 и 2, конечно, требуют тактов, только для моего случая п. 1. требуется выполнить только 1 раз для всех итераций цикла, на этапе составления списка инструкций СМК.

Надеюсь, моя мысль будет так понятнее.

Изменено пользователем Arlleex

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Надеюсь, моя мысль будет так понятнее.

Условия в рантайме меняются или нет?

Если нет, то компилятор сам выкинет заведомо ложные и исполнит заведомо истинные условия.

А если они меняются в рантайме, то и ваш генератор СМК должен все эти условия проверить,

сгенерить год и исполнить его.

По моему, даже если вы выиграете на исполнении СМК, то скорее всего проиграете на подготовке СМК.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Пусть есть некий цикл, но внутри этого цикла подряд идут условно выполняемые команды:

while(условие)
{
    if(условие 1)
        инструкция 1;

    if(условие 2)
        инструкция 2;

    if(условие 3)
        инструкция 3;

    ...

    if(условие N)
        инструкция N;
}

Потрясающе!!!! Вы угадали прямо в точку! Именно такой алгоритм я и хочу переделать на СМК! Потрясающая проницательность! :08:

 

Конкретней:

у меня сейчас есть участок кода примерно такой:

char *s;

if (map & 1 << 0) копирование 16 или 32 бит в *s с его постинкрементом на соотв. величину из источника, адрес которого берётся из таблицы для данной битовой позиции карты

if (map & 1 << 1) копирование 16 или 32 бит в *s с его постинкрементом на соотв. величину из источника, адрес которого берётся из таблицы для данной битовой позиции карты

if (map & 1 << 2) копирование 16 или 32 бит в *s с его постинкрементом на соотв. величину из источника, адрес которого берётся из таблицы для данной битовой позиции карты

...

if (map & 1 << 11) копирование 16 или 32 бит в *s с его постинкрементом на соотв. величину из источника, адрес которого берётся из таблицы для данной битовой позиции карты

всего 12 таких операторов.

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

А всё это вызывается с довольно неплохой частотой из ISR.

В то же время одновременно установленными может быть не более некоторого числа бит в карте (примерно около 10 максимум). Но всё равно сколько бит установлено в карте - всё равно будет выполняться вся эта портянка кода - это самое неприятное. Т.е. - даже когда эта функция выключена (битовая карта map==0), то процессор всё равно будет тратить кучу времени на выполнение всех этих 64 шагов. При статическом построении алгоритма.

Вот тут то и пришла в голову идея при каждом изменении map строить динамически код. map изменяется очень редко - не чаще раза в секунду.

 

PS: Вобщем генератор уже написан, осталось отладить :)

 

действительно, интерпретатор намного эффективнее и проще в реализации.

Уже в N-раз повторяю: РАЗГОВОР О СКОРОСТИ ВЫПОЛНЕНИЯ КОДА!!! Причём тут интерпретатор???

 

мда. присоединюсь про другое железо. Явно Allwinner просится

Блин! причём тут allwinner, если у меня МК заточенный своей периферией под конкретную задачу - motor control. И куча периферии задействована. Эта функция - лишь небольшая сервисная часть.

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Условия в рантайме меняются или нет?

Конечно меняются. Это обычные переменные, которые взводятся/сбрасываются где-то выше по коду или вовсе в других его частях.

А если они меняются в рантайме, то и ваш генератор СМК должен все эти условия проверить, сгенерить год и исполнить его.

Так выигрыш то огромен, если список таких условных ветвей достаточно большой. Даже из 10 условных команд, в случае, если эти команды нужно выполнить все (худший случай с точки зрения затраченного времени выполнения), понадобится 20 тактов (при условии, что все команды однотактные и условно выполняемая инструкция одна) без СМК. А применив СМК - цикл сократится до 10 тактов (без накладных расходов на проверку условия цикла). В лучшем случае, если только 1 условие верно, нужно выполнить только 1 инструкцию вместо 20 (10 связок "команда сравнения - команда самого условно выполняемого действия") выигрыш в 20 раз! Это ли не здорово?

По моему, даже если вы выиграете на исполнении СМК, то скорее всего проиграете на подготовке СМК.

Достаточно написать перед этим интересующие участки на ассемблере, скомпилировать их и видеть в бинарнике готовые инструкции в виде машинных слов. Easy же :rolleyes:

Потрясающе!!!! Вы угадали прямо в точку! Именно такой алгоритм я и хочу переделать на СМК! Потрясающая проницательность!

Я просто телепат B)

Изменено пользователем Arlleex

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Вот именно. Даже полностью строит процедуру. Вот такой примерно должен быть результат (код) работы генератора:

;Назначение регистров в динамически генерируемой функции.
dstReg         EQU      c_R0  ;указатель на целевой буфер для записи (вх.аргумент)
tblReg         EQU      c_R1  ;указатель на таблицу адресов переменных (вх.аргумент)
tmpReg0        EQU      c_R2  ;рабочий регистр 0
tmpReg1        EQU      c_R3  ;рабочий регистр 1
;сама функция 
;f0            LDR      tmpReg0, [tblReg, #bit1*4]; где bit1 - номер первого единичного бита в мл.слове бит-карты
;f0            LDR      tmpReg1, [tblReg, #bit2*4]; где bit2 - номер второго единичного бита в мл.слове бит-карты
;f1            LDR/LDRH tmpReg0, [tmpReg0]
;f2            STR/STRH tmpReg0, [dstReg], #step;   где step==4 для STR и step==2 для STRH
;f0            LDR      tmpReg0, [tblReg, #bit3*4]; где bit3 - номер 3-го единичного бита в мл.слове бит-карты
;f1            LDR/LDRH tmpReg1, [tmpReg1]
;f2            STR/STRH tmpReg1, [dstReg], #step;   где step==4 для STR и step==2 для STRH
;f0            LDR      tmpReg1, [tblReg, #bit4*4]; где bit4 - номер 4-го единичного бита в мл.слове бит-карты
;f1            LDR/LDRH tmpReg0, [tmpReg0]
;f2            STR/STRH tmpReg0, [dstReg], #step;   где step==4 для STR и step==2 для STRH
;              ...
;f3            ADDS     tblReg, tblReg, #32*4; вставляется при переходе к ст.слову бит-карты если в нём есть единицы
;f0            LDR      tmpReg0, [tblReg, #bit1*4]; где bit1 - номер 1-го единичного бита в ст.слове бит-карты
;f1            LDR/LDRH tmpReg1, [tmpReg1]
;f2            STR/STRH tmpReg1, [dstReg], #step;   где step==4 для STR и step==2 для STRH
;f0            LDR      tmpReg1, [tblReg, #bit2*4]; где bit2 - номер 2-го единичного бита в ст.слове бит-карты
;f1            LDR/LDRH tmpReg0, [tmpReg0]
;f2            STR/STRH tmpReg0, [dstReg], #step;   где step==4 для STR и step==2 для STRH
;              ...
;f1            LDR/LDRH tmpReg1, [tmpReg1]
;f2            STR/STRH tmpReg1, [dstReg], #step;   где step==4 для STR и step==2 для STRH
;f4            BX       LR

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

 

Как видно, в любом случае нет больше в цикле инструкций проверки условий в if(...)-ах (а они же ведь по сути Bxx в ассемблерном представлении) (да и куда лучше вовсе не проверять заранее ложные условия по списку), а выполняются только нужные инструкции сразу, как будто условных конструкций и нет. А п. 1 и 2, конечно, требуют тактов, только для моего случая п. 1. требуется выполнить только 1 раз для всех итераций цикла, на этапе составления списка инструкций СМК.

Надеюсь, моя мысль будет так понятнее.

Блин, коллега, позвольте пожать Вашу руку! Вы - похоже почти единственный человек на этом форуме сходу понявший все нюансы!!! :rolleyes:

 

Я просто телепат B)

Как будто заглянули в мои исходники! B)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Блин, коллега, позвольте пожать Вашу руку! Вы - похоже почти единственный человек на этом форуме сходу понявший все нюансы!!! :rolleyes:

О результатах сообщите, пожалуйста, удалось/не удалось внедрить, буду держать на всякий случай идею такую. Я довольно плотно поработал с битовой графикой на LCD/TFT дисплеях и организовывал меню разной степени вложенности для пользователей устройств с тачскрином/кнопками и экраном. Там таких ситуаций, где флажки надо опрашивать и определять отрисовки, да на каждом шагу по 50 :biggrin:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

О результатах сообщите, пожалуйста, удалось/не удалось внедрить, буду держать на всякий случай идею такую. Я довольно плотно поработал с битовой графикой на LCD/TFT дисплеях и организовывал меню разной степени вложенности для пользователей устройств с тачскрином/кнопками и экраном. Там таких ситуаций, где флажки надо опрашивать и определять отрисовки, да на каждом шагу по 50 :biggrin:

Ок. Генератор написал, но отлаживать буду завтра - поздно уже. Как заработает - напишу.

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

Переменные пока только 16- и 32-битные (целочисленные и float). Каждая битовая позиция в карте закреплена жёстко за какой-то переменной. И есть таблица указателей на эти переменные.

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

Вот примерно так.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

Идея понятна, идея здравая, сам делаю постоянно такие связки в проектах на МК + CPU (в одной плате). В сервисных структурах обмена указываю, какие переменные в нужном ответном массиве ожидаю в следующей посылке. Идея такая же, только у меня там пока что индусский код (но небольшой), а не СМК.

Кстати, видел как еще СМК спасает именно заменой порождающего кода особенно в математических операциях, где цикличные действия зависят от знака некой величины: в таком случае инструкции add заменяется sub и копируется в ОЗУ на выполнение. Ну и куча сопутствующих примеров.

ИМХО, главное в порыве радости весь проект не перелопатить на СМК - проклянешь себя через год, взглянув на код :smile3046: :biggrin:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

...

if (map & 1 << 11) копирование 16 или 32 бит в *s с его постинкрементом на соотв. величину из источника, адрес которого берётся из таблицы для данной битовой позиции карты

всего 12 таких операторов.

А чем DMA не подошёл?

ИМХО, главное в порыве радости весь проект не перелопатить на СМК - проклянешь себя через год, взглянув на код :smile3046: :biggrin:

А для меня лично загадка что вы называете словом СМК :biggrin:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Интересная тема для меня, тема СМК. Ни разу не применял,...

 

и не применяйте...

представьте себе вы вместо ифа позвали обработчик подпрограммы, а оно само знает какое подставиться...

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

 

(круглый)

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А для меня лично загадка что вы называете словом СМК :biggrin:

СамоМодифицирующийся Код :)

 

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

Как никак, ООП и СМК все-таки есть разнородные подходы к построению программных средств. На ООП без дублирования кода виртуальных методов для всех возможных комбинаций не возможна реализация подхода, даваемого СМК. Это все довольно обширные темы для разговора, и как-никак, они ортогональны, ИМХО.

представьте себе вы вместо ифа позвали обработчик подпрограммы, а оно само знает какое подставиться...

Здорово, не так ли? B) Ну а если серьезно, то я придерживаюсь принципа: нужно придерживаться максимально золотой границы между читабельностью кода и его функциональной смысловой нагрузкой. Уж выделить 0.0001% кода для СМК, особенно, если он там уж очень гладко ложится, есть комильфо.

 

Изменено пользователем IgorKossak

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...