Динамическое самопрограмирование сверхбыстрых подпрограмм без ветвлений - копирование и арифм и битовые операции для увеличения эффективности пользы от очереди команд микропроцессора. Как известно, современные микропроцессоры имеют очередь команд и могут одновременно выполнять нес-ко. но если переход по условию, то очередь очищается. так же если идут подряд зависимые команды типа R1=55 R2=R1+4 то очередь тоже малоэффективна, нужно вставлять между ними еще что-то R1=55 R3=99 R4=1234 R2=R1+4 тогда первые 3 команды можно выполнить паралельно а потом 4ю Так вот метод динамического програмирования заключается в том, что обычная программа на ассемблере с ветвлениями, которая по задумке должна выполняться 1000 раз и как можно быстрее, вместо того чтобы исполняться, ставит на load save перехватчики, а они вместо записи/чтения генерируют команды в свободное место озу: (адрес)=данные, причем регистр=адрес и регистр=данные можно поднять выше на нес-ко команд. Затем ставит на себя заглушку и переход JUMP на новый сгенерированный код. Рассмотрим конкретный пример. копируем вирт экран на реальный но не весь а только какие то части например внеш. окно и внутр окно циклы по х и у If (x < X1) Then GoTo m0 If (x > X2) Then GoTo m0 If (y < Y1) Then GoTo m0 If (y > Y2) Then GoTo m0 If (x < x1) Then GoTo ok1 If (x > x2) Then GoTo ok1 If (y < y1) Then GoTo ok1 If (y > y2) Then GoTo ok1 GoTo m0 ok1: 'копируем байт с вирт на реал экран ADR1 = adr1+х+у*Max_X ADR2 = adr2+х+у*Max_X R = (ADR1) (ADR2) = R m0: 'сюда если граничные условия нарушены конец цикла можно конечно 4 прямоугольника скопировать-чуть быстрее но из-за ветвлений все равно не то, очередь команд практически не используется.. (А если условий ещё больше, то разбивка на части- совсем не тот путь..) В реале есть нес-ко вирт экранов и они выводятся последовательно для анимации меняется только адрес источника. Если эта же программа будет вместо непосредственно чтения/записи генерировать соотв. машинный код типа: SUB COPY_MEM_HIGH_SPEED Rt2=(Rv1) Rt3=(Rv1+?) Rt4=(Rv1+?) Rt5=(Rv1+?) Rt6=(Rv1+?) Rt7=(Rv1+?) Rt8=(Rv1+?) Rt9=(Rv1+?) (Rv1)=Rt2 (Rv1+?)=Rt3 (Rv1+?)=Rt4 (Rv1+?)=Rt5 (Rv1+?)=Rt6 (Rv1+?)=Rt7 (Rv1+?)=Rt8 (Rv1+?)=Rt9 Rt2=(Rv1+?) Rt3=(Rv1+?) Rt4=(Rv1+?) Rt5=(Rv1+?) Rt6=(Rv1+?) Rt7=(Rv1+?) Rt8=(Rv1+?) Rt9=(Rv1+?) (Rv1+?)=Rt2 (Rv1+?)=Rt3 (Rv1+?)=Rt4 (Rv1+?)=Rt5 (Rv1+?)=Rt6 (Rv1+?)=Rt7 (Rv1+?)=Rt8 (Rv1+?)=Rt9 итд. сколько есть RETURN ?-смещение вычисляется по ходу работы исходной программы, также по ходу можно вставлять регистр=данные, выше чем команда с этим регистром дальше. итого имеем - одновременно можно выполнять сразу 8 команд и ветвлений НЕТ. а это значит эффективость очереди команд будет непрерывной и скорость выше в миллион раз :) Недостатки-надо много памяти, но это временно. потом она освобождается.. По сути это разворачивание коротких циклов в линию и вместо последовательного выполнения будет паралельное без возвратов. Так же могут быть обходы которые можно раздвоить на 2 копии и при разных начальных условиях выполнять ту или иную ветку без остановок на проверки. Еще случай: видеопамять экрана 1 байт-2 точки. шрифт-1байт-4 точки. разворачиваем временную копию в озу 1 байт-1 точка. В итоге ускорение за счет избавления от повторяющегося декодирования и упаковки (считать+сдивинуть+логич ИЛИ) ну и циклов меньше-прямое копирование, которое за счет использования разных регистров(а их в мипсе аж 32 шт) a4 v2 fpgp s8 t10 at k2 hi lo r0 но одновременно можно только 25х4=100 байт копировать. в z80 были команды массового копирования, но они выполнялись последовательно и медленно. Были и программы которые 1) сжимали(зиповали) exe-шники которые сделаны с опцией: оптимизировать по скорости. - и они на диске занимали меньше места, а при загрузке-восстанавливались 2) делали из оптимизированых по размеру в оптимизированные по скорости. но они не умели разворачивать циклы, т.к не знали какие регистры можно использовать безопасно и тогда озу было маленькое, про очередь команд и намеков не было. есть конечно кеш, но туда всю прогу не закинеш. Теперь память больше гига-норма. так что для ускорялок можно половину спокойно занять. Для MIPS SunPlus актуально только попарное распаралеливание:очередь команд=2 и еще похоже регистры кэшируются в пределах 2х следующих инструкций. Так же можно предварительно декодировать символы в спрайты и их кешировать. Если вх. значений у функции немного, то вместо расчетов лучше использовать заранее расчитанные таблицы (или предварительно расчитать и создать в озу) Может это уже давно и где-то используется, но я пока не видел и не слышал. может я и переизобрел очередной велосипед.. по крайней мере когда я учился и читал умные книжки по програмированию 10-20 лет назад- такого не было 100%. а в последние годы я ничего специально не читал, тока проги чужие ковыряю, и иногда в инете случайные статьи. Меня сейчас другое волнует:) Откуда зимой кислород, если деревья без листьев? некому фотосинтезом заниматься.. 4 авг 2014г Xing. При перепечатке ссылка на источник обязательна.