PDA

Просмотр полной версии : TST (RO)+; CMP (R0)+,(R0)+



S_V_B
22.10.2020, 11:00
Вопрос к знающим, вышеуказанные фишки - это пижонство или реально доказанный факт?
Было бы круто получить полный список "ускорителей":)
В некоторых источниках встречал, что работа со стеком быстрее (сомневаюсь)..
Прошу выкладывать в этой теме все, что может ускорить исполнение:)

- - - Добавлено - - -

Начну сам (общеизвестное)
XCHG (обмен регистров)

XOR R0,R1
XOR R1,R0
XOR R0,R1
Насколько это быстро? Или проще использовать промежуточный регистр?

- - - Добавлено - - -

Не нужно сразу взрываться сарказмами... только по делу. Неофитам будет очень полезно :) Да и мне если кто, что умное скажет:)

- - - Добавлено - - -


MOV #100, END+2
Begin: .....
END: DEC #0
BNE Begin
Такой цикл быстрее или мы просто экономим регистр?

- - - Добавлено - - -

Вариантов много которые я раскопал, нужно оформить (если есть смысл) в формате библии А3, чтобы некоторое время висела перед носом:)

Alex
22.10.2020, 12:41
Вопрос в том, для чего нужен этот промежуточный регистр...
Экономия регистра - это не самоцель. Это обычно для чего-то нужно.
Цикл в той форме - медленней

gid
22.10.2020, 14:26
Цикл в той форме - медленней
Но быстрее, чем

COUNT: .WORD 0
.....
MOV #100, COUNT
Begin: .....
DEC COUNT
BNE Begin
Поэтому и использовали адресацию 27 вместо 67/37, чтобы 1) ускорить выполнение за счёт уменьшения на 1 цикл доступа к памяти; 2) сэкономить одно слово. А если нужно быстродействие, лучше использовать регистры.

Кстати CMP (R0)+,(R0)+ тоже медленнее, чем ADD #4,R0

S_V_B
22.10.2020, 14:45
Значит в большинстве случаев это:
1. Экономия памяти.
2. Во всех остальных - пижонство.

Alex
22.10.2020, 15:04
И ещё:
Насчёт того, где медленнее, а где быстрее, надо смотреть на конкретную машину и процессор.
Архитектура может отличаться. Например память на ферритах :)
Или наличие кэша... Лишние пару слов в программе, могут привести к тому, что программа в кэш не лезет, соответственно будут тормоза.
Или предвыборка на 1801ВМ3...
Программа в ПЗУ(только чтение).
Архитектура с I/D пространством.
Вариантов море...

Так что тут надо рассматривать каждую отдельно взятую машину, смотреть требования к программе и делать выводы типа:
1. Здесь делаем так и так.
2. Здесь делам иначе...
3. А здесь пишем так, чтобы быстрее написать :) никаких напрягов здесь нет ...(большая часть случаев)
Как-то так...

S_V_B
22.10.2020, 15:20
Так что тут надо рассматривать каждую отдельно взятую машину, смотреть требования к программе и делать выводы типа:
В данном случае мы рассматриваем УКНЦ (ВМ2) и слава богу память не на ферритах :)

Alex
22.10.2020, 17:34
Ну про то, что разговор идёт про УКНЦ (1801ВМ2) узнал только сейчас...
И Нunta, судя по быстродействию, тоже не про УКНЦ (1801ВМ2) ...

А так, вполне может оказаться вместо на УКНЦ вместо 1801ВМ2, 1806ВМ2.
Есть такая тема тут на форуме :)

Да и для БК мутили модули аж с 1801ВМ3 ;)

Hunta
22.10.2020, 17:50
Из занимательного (1801ВМ3)


.RUN SPEED3

Тест быстродействия

...
#4+R0(2000) empty 622 695 оп./сек
#4+R0(2000) 311 737 оп./сек -> 624 254 оп./сек
CMP (R0)+,(R0)+ empty 623 474 оп./сек
CMP (R0)+,(R0) 173 957 оп./сек -> 241 276 оп./сек

#2+R0(2000) empty 623 474 оп./сек
#2+R0(2000) 311 736 оп./сек -> 623 470 оп./сек
INC R0 INC R0 empty 623 473 оп./сек
INC R0 INC R0 389 586 оп./сек -> 1 038 520 оп./сек
TST (R0)+ empty 623 473 оп./сек
TST (R0)+ 271 157 оп./сек -> 479 850 оп./сек
...

Пока не могу сказать насчёт правильности - начал менять SPEED3 - возможны ошибки..

Titus
22.10.2020, 17:51
Ну про то, что разговор идёт про УКНЦ (1801ВМ2) узнал только сейчас...
S_V_B ведет разработку игр под УКНЦ, а там только ВМ2.

Alex
23.10.2020, 10:23
Я не вижу особой проблемы посадить, по образу и подобию БК модуля на 1801DM3, на разъём сетевого адаптера ;) Например...
Можно и что-то другое. Сейчас добьют чипы к УКНЦ, станет известно точно как они работают и всё в руках желающих...
Нужны только прямые руки и время.

Hunta
23.10.2020, 10:26
Я не вижу особой проблемы посадить, по образу и подобию БК модуля на 1801DM3
Проблем особых нет, нужно только время и желание, но вот в чём прикол - много ли ты знаешь владельцев БК, которые а) сделали это и б) пишут игры?

Titus
23.10.2020, 10:50
Я не вижу особой проблемы посадить, по образу и подобию БК модуля на 1801DM3, на разъём сетевого адаптера Например...
Можно и что-то другое. Сейчас добьют чипы к УКНЦ, станет известно точно как они работают и всё в руках желающих...
Нужны только прямые руки и время.
Чипы уже добиты.

УКНЦ на ВМ3 вряд ли особо кому-то пригодится. Не говоря уже о софтописании.

Hunta
23.10.2020, 11:29
УКНЦ на ВМ3 вряд ли особо кому-то пригодится. Не говоря уже о софтописании.
ЧИТД

Manwe
28.10.2020, 10:17
Вопрос к знающим, вышеуказанные фишки - это пижонство или реально доказанный факт?Я постоянно так делаю ради экономии памяти в интрах и в драйверах.
Ещё часто использую такую оптимизацию размера и количества регистров при работе с циклами:

MOV #Size,R0
1: действие с ARRAY-1(R0)
SOB R0,1

Если нужно работать не с байтами, а со словами, то так:

MOV #Size*2,R0
1: действие с ARRAY-2(R0)
DEC R0
SOB R0,1

S_V_B
31.10.2020, 16:59
MOV #Size,R0
1: действие с ARRAY-1(R0)
SOB R0,1
Здесь в чем фокус?
Все так делают наверно.
Хотя SOB мне не нравится.. нужно спросить у знатоков что быстрее SOB или BNE

Manwe
04.11.2020, 00:24
Здесь в чем фокус?Массив обрабатывается от конца к началу и не тратится регистр на адрес массива. Обычно делают "в лоб": в одном регистре адрес массива, в другом индекс, в третьем счётчик.



Хотя SOB мне не нравится.. нужно спросить у знатоков что быстрее SOB или BNEBNE реагирует на содержимое массива, а нам нужен индекс.

nzeemin
06.11.2020, 18:50
В коде прошивок от Электроника МС 0515 часто встречается такой приём.
Допустим, вам нужно сделать что-то с двумя массивами или двумя портами, двумя блоками на экране итп. - однотипные операции, но в двух местах.
Делается цикл который исполняется ровно два раза:


MOV 2,R2
MOV XXXXXX,R1 ; первое место
LOOP:
. . . ; Делаем что-то полезное по адресу R1

MOV YYYYYY,R1 ; второе место
SOB R2,LOOP ; повторяем второй раз

Hunta
06.11.2020, 19:10
MOV 2,R2 -> MOV #2,R2

nzeemin
06.11.2020, 19:10
MOV 2,R2 -> MOV #2,R2

Ну да. моя типичная ошибка.

BlaireCas
26.11.2020, 18:15
Я как непривыкший к ассемблеру постоянно делаю так:



DEC VAR
BNE 10$ ; часто происходящая ситуация
... ; а тут редко происходящая
RETURN
10$: ... ; продолжаем операцию


Постоянно подозрения что ветвления надо делать по минимуму, но .. Вообщем все эти моменты продумывать - уедет мозг :) Респект конечно монстрам ассемблерного программирования.

Hunta
26.11.2020, 18:26
делаю так
Насколько я себе представляю - на ВМ2 и ВМ3 будет сбиваться конвейер

BlaireCas
10.12.2020, 17:34
Вот еще вопрос кстати пришел на ум. В нашем ассемблере есть абсолютная и относительная адресации (кроме других). В зависимости от указаний ассемблеру он по-разному скомпилирует например такое:

1) при директиве .ENABL AMA


clr VAR000 ; 005037 002000 (абс. адрес)
; эквивалентно clr @#VAR000


2) без принуждения абсолютной адресации


clr VAR000 ; 005067 001420 (cмещение)


И вот что-то я никогда обычно принудительно директиву абсолютной адресации не ставил. А тут задумался - оно ведь должно быстрее работать, или нет?
(при абсолютном адресе процессору ведь не надо ничего складывать чтобы адрес получить... вроде)

Titus
10.12.2020, 18:32
А тут задумался - оно ведь должно быстрее работать, или нет?
Давай рассмотрим два твоих варианта основываясь на микрокоде ВМ2.

@(PC)+ (абсолютный адрес переменной):
1. Ожидаем готовности BRI (буферного регистра инструкции), чтобы в него загрузилось следующее слово
2. АЛУ: Вычисляем адрес = BRI (4 такта) и запрашиваем цикл чтения шины
3. Ожидаем готовности BRD (буферного регистра данных)
4. АЛУ: Вычисляем CLR (4 такта) и запрашиваем цикл записи шины
5. Переходим на команду выбора следующей некэшированной инструкции (т.к. мы адресовались по R7).

X(PC) (относительный адрес переменной):
1. Ожидаем готовности BRI (буферного регистра инструкции), чтобы в него загрузилось следующее слово
2. АЛУ: Вычисляем адрес = BRI+PC (4 такта) и запрашиваем цикл чтения шины
3, 4, 5 шаги такие же, как и в предыдущем варианте.

Итого, по скорости абсолютно все равно, какой вариант.

- - - Добавлено - - -


(при абсолютном адресе процессору ведь не надо ничего складывать чтобы адрес получить... вроде)
АЛУ у ВМ2 очень гибкое, и легко вычисляет сложные исполнительные адреса одной операцией.

Alex
10.12.2020, 18:36
Но это справедливо именно для 1801ВМ2... Благо его исследовали :)
Для других процессоров могут быть сюрпризы ...

BlaireCas
10.12.2020, 20:41
2. АЛУ: Вычисляем адрес = BRI (4 такта) и запрашиваем цикл чтения шины
...
2. АЛУ: Вычисляем адрес = BRI+PC (4 такта) и запрашиваем цикл чтения шины
...
АЛУ у ВМ2 очень гибкое, и легко вычисляет сложные исполнительные адреса одной операцией.


Проверил на железке. Убедился что скомпилировались разные команды (005067 и 005037)
Так и есть. Время абсолютно одинаково. (64.34сек на 10m операций clr memory с оверхедом на ~1m sob-ов, кст небыстро)

Но... Но .. как, Холмс? (с)
Ведь надо-же сначала сложить, а потом отправлять адрес на шину...



.MCALL .exit, .gtim, .ttyout, .gval

.radix 10
CONFIG = ^O300

START: ; test 1
.gtim #area, #time
call PAYLD1
call PRIDIF
; clearing just in case
mov #time, R0
mov #6, R1
clr (R0)+
sob R1, .-2
; test 2
.gtim #area, #time
call PAYLD2
call PRIDIF

.exit

; payload 1
VAR000: .WORD 0
PAYLD1: mov #1000, R3
5$: mov #1000, R2
10$: clr VAR000
clr VAR000
clr VAR000
clr VAR000
clr VAR000
clr VAR000
clr VAR000
clr VAR000
clr VAR000
clr VAR000
sob R2, 10$
sob R3, 5$
return

; payload 2
PAYLD2: mov #1000, R3
5$: mov #1000, R2
10$: clr @#VAR000
clr @#VAR000
clr @#VAR000
clr @#VAR000
clr @#VAR000
clr @#VAR000
clr @#VAR000
clr @#VAR000
clr @#VAR000
clr @#VAR000
sob R2, 10$
sob R3, 5$
return

; print diff in sec
PRIDIF:
mov #time2, r1
.gtim #area, r1
sub @#time+2, @#time2+2
sbc @#time2
sub @#time, @#time2

mov @#time2, r2
mov @#time2+2, r3
asl r3
rol r2
.gval #area, #CONFIG
mov r0, r4
mov r3, r1
mov r2, r0
bit #32, r4 ;50 or 60 Hz?
bne l206

asl r1 ;*5
rol r0
add @#time2+2, r1
adc r0
add @#time2, r0
asl r1 ; divisor is limited to 15 bits!
rol r0
mov r0, r3
clr r2
div #3, r2
mov r3, r0
asr r0
ror r1
div #3, r0
asr r1
add r0, r1
clr r0
asr r2
ror r0
add r0, r1
adc r2
mov r2, r0
l206: call @#printsec ; prints r0:r1
mov #10, r0
.ttyout
mov #13, r0
.ttyout
return

; prints R0:R1/100
printsec:
mov r1, r2
mov r0, r1
clr r4
mov #1, r5
mov #34464, r3 ;100000-65536
call @#20$
clr r5
mov #10000, r3
call @#20$
mov #1000, r3
call @#20$
inc r4
mov #100, r3
call @#20$
movb #'., r0
.ttyout
mov #10, r3
call @#20$
mov r2, r0
2$: add #48, r0
.ttyout
inc r4
5$: return
7$: tst r4
bne 2$
tst r0
beq 5$
inc r4
br 2$
20$: mov #65535, r0
4$: inc r0
cmp r1, r5
bcs 7$
bne 8$
cmp r2, r3
bcs 7$
8$: sub r3, r2
sbc r1
sub r5, r1
br 4$

time: .word 0, 0 ; high, low!
time2: .word 0, 0
area: .word 0, 0

.END START


(кст вывод секунд не мой, взят и теста числа ПИ на разных процессорах, вроде честно выдает)

Titus
10.12.2020, 21:24
Но... Но .. как, Холмс? (с)
Ведь надо-же сначала сложить, а потом отправлять адрес на шину...
Посмотри тему с описанием микрокоманд, и все станет понятно)
Еще раз повторюсь, что АЛУ все равно, просто скопировать ссылку на адрес в регистр RA, или же еще заодно и сложить его с PC.