╔═---- ------ ----- --
║ ##########Несколько способов ###### |
| ##############облегчить########### |
| #############себе жизнь.######### ║
-- ---- ------ ---------═╝
HIGHLANDER, Infotek.
E-MAIL: м14369@chat.ru
То, о чём пойдёт речь не является истиной
в последней инстанции, и не рассматривает-
ся как руководство к действию, каждый
должен сам определять необходимость при-
менения того или иного метода в своих
программах и разработках.
Не побоюсь утверждать, что каждый начи-
нающий кодер не раз сталкивался с одной
праблой: прога работает меееееедлееееено,
спрайты (не в бутылках) как заснули, и т.п
Причин может быть много, начиная с того
на чём сие творение написано, заканчивая
тем как написано (клинические случаи пос-
ледователей дяди Билли не рассматриваются,
у них так задумано).
Начну с так называемых "раскрытых циклов"
если кто ещё не понял, привожу примерчик,
в поле коментария - длительность команды
в тактах Z8O:
: Kусочичек процедуры печати, который
: осуществляет печать буквы на экране
: (с точностью до знакоместа)
: HL - адрес в экране
: DE - адрес буквы в фонте
:
LD В,8 : 7
LOOP LD A,(DE) : 7
LD (HL),A : 7
INC DE : 6
INC H : 4
DJNZ LOOP : 8/13
Немного математики не помешает,
7+7*(7+7+6+4+13)+7+7+6+4+8=298 тактов,
а если раскрыть цикл, получим:
LD A,(DE) : 7
LD (HL),A : 7
INC DE : 6
INC H : 4
LD A,(DE) : 7
LD (HL),A : 7
INC DE : 6
INC H : 4
LD A,(DE) : 7
LD (HL),A : 7
INC DE : 6
INC H : 4
LD A,(DE) : 7
LD (HL),A : 7
INC DE : 6
INC H : 6
LD A,(DE) : 7
LD (HL),A : 7
INC DE : 6
INC H : 4
LD A,(DE) : 7
LD (HL),A : 7
INC DE : 6
INC H : 4
LD A,(DE) : 7
LD (HL),A : 7
INC DE : 6
INC H : 4
LD A,(DE) : 7
LD (HL),A : 7
Путём несложных расчётов получим:
7*(7+7+6+4)+7+7=182 такта, что на 38.926%
быстрее, если учесть, что в строке 32
символа, получим экономию 3712 тактов,
неплохо, неплохо... Но воистину програм-
мист от бога заметит, что первый вариант
в памяти занимает 8 байт, а второй - 3O.
Из этого вытекает маленькая аксиома:
"Скорость работы программы прямопропор-
циональна её размеру."
Кстати, LDIR (LDDR) циклическая команда,
а LDI (LDD) нет, значит всё вышеизложен-
ное можно применить и к ним:
LD HL,#COOO : откуда
LD DE,#ЧOOO : куда
LD ВС,#OOO8 : сколько
LDIR : 21/16 тактов на
: каждый байт
LDIR пересылает один байт за 21 такт,
если ВС<>O или за 16, если ВС=O. Заменив
LDIR на LDI получим следующее:
LD HL,#COOO : откуда
LD DE,#ЧOOO : куда
LDI :
LDI : каждый
LDI :
LDI : LDI
LDI :
LDI : 16 тактов
LDI :
LDI :
Причём число повторений LDI равно числу,
которое засылалось в ВС при использовании
LDIRа.
Таким образом можно разогнать программу
довольно таки заметно, но не стоит этим
злоупотреблять, память у вас не РCишная,
может не хватить. Советую раскрывать те
циклы, которые часто вызываются головной
программой.
Следующим на повестке дня вопрос о
"быстрой графике", методике, пзволяющей
осуществлять перемещения данных (не обя-
зательно графических) со скоростью выше
LDIRров и LDIшек.
╔══════════════════════════════╗
║╔--- ---══--- ---╗║
║|+--------------------------+|║
║ | ВНИМАНИЕ | ║
║ | ДАБЫ НЕ ВОЗНИКАЛО | ║
║|| КРИТИЧЕСКИХ СИТУАЦИЙ ||║
║║|ПЕРЕД ПРИМЕНЕНИЕМ ПРОЦЕДУР|║║
║|| ИСПОЛЬЗУЮЩИХ СТЕК ||║
║ | ПРЕРЫВАНИЯ ДОЛЖНЫ БЫТЬ | ║
║ | ЗАПРЕЩЕНЫ!!! | ║
║|+--------------------------+|║
║╚--- ---══--- ---╝║
╚══════════════════════════════╝
Суть метода в использовании стека не по
прямому его назначению. Теория: команды
PUSH или POP кладут на или снимают с вер-
шины стека два байта, вроде бы в этом нет
ничего особенного, если не одна деталь,
PUSH - 11 тактов, а POP - 1O. Но как это
использовать? Элементарно, Ватсон, поме-
щаем стек на начало данных и POPaми эти
самые данные берём, и что хотим, то и де-
лаем. Примерно так:
LD (SAV_SP+1),SP : сохраняем SP
LD SP,#COOO : стек на нужный
: адрес
POP HL : 2 байта взяли
LD (#ЧOOO),HL : куда надо, туда
: и положили
POP HL : следующие
LD (#ЧOO2),HL : 2 байта
......
POP HL : последние
LD (#SAFE),HL : 2 байта
SAV_SP LD SP,#OOOO : восстанавливаем
: SP
Снова математика: POP HL и LD (NNNN),HL
выполняются 1O+16=26 тактов и пересылают
два байта, а два LDI - 32 такта, как гово-
рится, результат на лице, получается 13
тактов на байт, но при этом необходимо,
чтобы массив данных был кратен двум (если
это спрайт, то его ширина кратна двум), я
считаю, что это небольшая плата за ско-
рость.
Вроде бы больше никак не разогнаться, но
это не так, чуть-чуть можно, но это только
на больших массивах:
LD (SAV_SP+1),SP : сохранить SP
М1 LD SP,#COOO : откуда
POP HL
POP DE
POP ВС
POP AF
EXX
EX AF,AF'
POP HL
POP DE
POP ВС
POP AF
LD SP,#4O1O : куда
PUSH AF
PUSH ВС
PUSH DE
PUSH HL
EXX
EX AF,AF'
PUSH AF
PUSH ВС
PUSH DE
PUSH HL
М2 LD SP,#CO1O : следующий
POP HL : блок данных
........
PUSH DE
PUSH HL
SAV_SP LD SP,#OOOO : восстанавливаем
: SP
Если подсчитать число тактов между мет-
ками М1 и М2, то получим 2O4 такта, а
скопируется 16 байт, лёгким движением из-
вилин получим: 12.75 такта на байт !!!
Быстрее не бывает, если кто-то придумает
более быстрый способ, пусть мне сообщит,
буду очень рад. Но тут есть маленькая осо-
бенность, из-за того, что стек растёт
сверху вниз, необходимо это учитывать при
расстановке адресов в процедуре.
Ну, дабы не быть голословным, процедура
быстрого заполнения файла атрибутов одним
цветом:
: с применением LDIRa
LD HL,#58OO
LD DE,#58O1
LD ВС,#O2FF
LD (HL),ATRIBUT
LDIR
: ИТОГО: 16142 такта
Другой вариант:
: с применением "быстрой графики"
LD (SAV_SP+1),SP
LD SP,#5BOO
LD HL,#NNNN : в H и L код
PUSH HL : атрибута
PUSH HL : PUSH HL
........ : повторяется
PUSH HL : 384 раза
PUSH HL : (768/2=384)
SAV_SP LD SP,#OOOO
: ИТОГО: 4274 такта
На сегодня новостей больше нет, поэтому
всем большой гудбай.
Копирайт мой, и негоже его менять.
Other articles: