Математические процедуры. — ZXNet «code.zx»

Математические процедуры.

ZXNet echo conference «code.zx»



from: Aleksey Malov
to: All
date: 4 April 2000
Приветствую тебя, All! Итак, процедура номер 1: быстрое деление 16/16. Тому, кто сможет ее ускорить, можно будет памятник при жизни поставить (за его счет). Ускорение путем замены jr на jp не рассматривается, т.к. выигрыш/ проигрыш в скорости зависит от величины аргументов. На входе: de-делимое bc-делитель На выходе: de-частное hl-остаток divide ld a,b ;меняем cpl ; ld b,a ;знак ld a,c ; cpl ;у ld c,a ; inc bc ;делителя t=30 ld hl,0 ;обнулили новое делимое ld a,d ;сначала двигаем rla ;старший байт делимого ;t=18 rl l ;┐ add hl,bc ;│ jr c,$+4 ;│8 раз sbc hl,bc ;│ rla ;┘ t=8*45=360 ld d,a ;ст. байт результата ld a,e ;теперь двигаем rla ;младший байт t=12 adc hl,hl ;┐ add hl,bc ;│ jr c,$+4 ;│8 раз sbc hl,bc ;│ rla ;┘ t=8*52=416 ld e,a ;мл. байт результата ;hl-остаток от деления ;t=4 Итого: 30+18+360+12+416+4=840 тактов. Если остаток не нужен, то конец проце- дуры должен выглядеть так: adc hl,hl ;┐ add hl,bc ;│ jr c,$+4 ;│7 раз sbc hl,bc ;│ rla ;┘ t=7*52=364 adc hl,hl ; add hl,bc ; rla ; ld e,a ; t=34 Итого: 30+18+360+12+364+34=818 тактов. P.S. Если будете делить на ноль, то, как и следовало ожидать, частное будет равно нулю, а остаток - делимому, т.е. в этом плане у процедуры глюков нет. ;*********************** Процедура номер 2: извлечение квадратного корня из регистровой пары. Вот тут уж действительно надо памятник поставить тому, кто ускорит процедуру хотя бы на 1 такт. Ускорение путем замены jr на jp не рассматривается, т.к. выигрыш/проигрыш в скорости зависит от величины аргумента. На входе: hl-число из которого необходимо извлечь квадратный корень на выходе: a-квадратный корень из hl sqrhl xor a ;обнулили a ;-) ld de,64 ;этого требует алгоритм ; t=14 sla h ;берем два самых левых adc a,a ;бита аргумента sla h ; adc a,a ; jr z,$+4 ;если они не равны dec a ;нулю, то увеличиваем inc d ;результат ; t=39 sla h ;┐далее следуем adc a,a ;│алгоритму извлечения sla h ;│квадратного корня adc a,a ;│"столбиком", только sla d ;│ ld c,d ;│3 раза sli c ;│ cp c ;│ jr c,$+4 ;│ sub c ;│ inc d ;┘ t=63*3=189 sla l ;┐проделываем похожую adc a,a ;│операцию с sla l ;│младшим байтом adc a,a ;│аргумента sla d ;│ ld c,d ;│2 раза sli c ;│ cp c ;│ jr c,$+4 ;│ sub c ;│ inc d ;┘ t=63*2=126 ld h,a ; or a ;обнулили флаг переноса ; t=8 sbc hl,de ;теперь нам не хватает jr nc,$+3 ;одного регистра d для add hl,de ;выполнения последних ccf ;двух циклов, придется rl d ;использовать более add hl,hl ;медленные операции add hl,hl ;с регистровыми парами ; t=67 sbc hl,de ;и последний раз ccf ;выполняем расчеты, не ld a,d ;восстанавливая hl adc a,a ;в a-результат ; t=27 Итого: 14+39+189+126+8+67+27=470 тактов. Процедура номер 3: извлечение квадратного корня из трехбайтового числа. Ускорение путм замены jr на jp не рассматривается, т.к. выигрыш/проигрыш в скорости зависит от величины аргумента. На входе: dhl=d*65536+hl - само число На выходе: hl - тот самый квадратный корень sqrdhl xor a ;начало процедуры ld bc,64 ;практически аналогично ;предыдущей ; t=14 sla d ; adc a,a ; sla d ; adc a,a ; t=39 jr z,$+4 ; dec a ; inc b ; sla d ;┐ adc a,a ;│ sla d ;│ adc a,a ;│ sla b ;│ ld e,b ;│3 раза sli e ;│ cp e ;│ jr c,$+4 ;│ sub e ;│ inc b ;┘ t=3*63=189 sla h ;┐ adc a,a ;│ sla h ;│ adc a,a ;│ sla b ;│ ld e,b ;│2 раза sli e ;│ cp e ;│ jr c,$+4 ;│ sub e ;│ inc b ;┘ t=63*2=126 ld d,l ; ld l,h ; ld h,a ;меняем регистры or a ; t=16 sbc hl,bc;┐ jr nc,$+3;│ add hl,bc;│ ccf ;│2 раза rl b ;│ add hl,hl;│ add hl,hl;┘ t=67*2=134 ld l,h ;есть подозрение, что ld h,0 ;этот блок и предыдущий ld c,b ;можно немного ускорить ld b,h ; rl h ; ld a,d ; t=31 rla ;┐да и этот блок мне adc hl,hl;│не нравится. rla ;│очень вероятно, что adc hl,hl;│его можно неплохо sla c ;│ускорить. Но как? rl b ;│ ld d,b ;│ ld e c ;│3 раза sli e ;│ rl d ;│ sbc hl,de;│ jr nc,$+4;│ add hl,de;│ dec c ;│ inc c ;┘ t=3*119=357 (!) ;ужас! Думайте, как ;ускорить! rla ;этот блок аналогичен adc hl,hl;предыдущему с rla ;небольшой разницей adc hl,hl;в конце. Это сделано ld d,b ;ради повышения ld e,c ;скорости вычислений sla e ; rl d ; sli e ; rl d ; sbc hl,de; ccf ; t=97 ld h,b ; ld l,c ; adc hl,hl;в hl - результат ; t=23 Итого: 14+39+189+126+16+134+31+357+97+23=1026. ;****************** Hу и процедура расчета адреса в аттрибутах по координатам в знакоместах. быстрее не сделать, если не использовать таблиц. На входе: d-y e-x На выходе: hl-адрес в аттрибутах ld a,d rrca rrca rrca ld h,a and #e0 or e ld l,a xor e xor h or #58 ld h,a t=54 такта. Желаю вам здоровья, счастья и творческих узбеков. Aleksey Malov aka VIVID/Brainwave.

from: Vitaly Vidmirov
to: Aleksey Malov
date: 5 April 2000
i`m happy to meet you again, Aleksey! last time (04 Apr 00 01:03:19) you talk about something AM> Итак, процедура номер 1: быстрое деление 16/16. Тому, кто сможет AM> ее ускорить, можно будет памятник при жизни поставить (за его счет). AM> divide ld a,b ;меняем AM> cpl ; AM> ld b,a ;знак AM> ld a,c ; AM> cpl ;у AM> ld c,a ; AM> inc bc ;делителя t=30 сразу же бросилось в глаза xor a sub c ld c,a sbc a,b sub c ld b,a 30 -> 24. Остальное посмотрю когда будет время. Hе забудь, что существуют и другие алгоритмы деления... catch my respects, Aleksey