Temat: wydajnościówka w Action!

tak sobie dzisiaj z Perinoidem porównywaliśmy wydajność prostego kodu w C i Action!

// powiel 40 bajtow cc65
    for(i=1; i<192; i++) {
        memcpy(ptr, video_ptr, 40);
        ptr+=40;
    }
; powiel 40 bajtow Action
FOR i=1 TO 192
   DO
          moveblock(ptr, video_ptr, 40)
          SCREEN==+40
   OD

dla ułatwienia - te same zmienne, typy etc. moveblock robi to samo co memcpy - czyli kopiuje zadaną liczbę bajtów na docelowe miejsce z wskazanego miejsca. Kopiowanie linii danych w pamięci ekranu - no i wydajnościowo - mówimy o mikroułamkach sekund, ale licząc ramki ekranu na grabberze to Action! robi to dokładnie dwa razy dłużej (0.2 sek. vs 0.1 sek.).

Pytanie - czy da się to szybciej w Action?

/|\ 400 - 800 Incognito+Supercard - 600XL 64k - 800XL - 1088XEL CF3 - XE GS Ultimate VBXE - SIO2SD - SIDE2 - CA2001 - 1050 - XF551 clone by Zaxon /|\ STE 4MB Ultrasatan /|\ 7800 /|\ PORTFOLIO

2

Odp: wydajnościówka w Action!

kod memcpy CC65 jest mocno optymalizowany, korzystam z niego w MP (MadPascal)

; Ullrich von Bassewitz, 2003-08-20
; Performance increase (about 20%) by
; Christian Krueger, 2009-09-13

.proc    @moveu            ; assert Y = 0

ptr1    = edx
ptr2    = ecx
ptr3    = eax

    stx @sp

    ldy    #0

    ldx     ptr3+1        ; Get high byte of n
    beq     L2        ; Jump if zero

L1:     .rept 2            ; Unroll this a bit to make it faster...
    lda     (ptr1),Y    ; copy a byte
    sta     (ptr2),Y
    iny
    .endr

    bne     L1
    inc     ptr1+1
    inc     ptr2+1
    dex            ; Next 256 byte block
    bne    L1        ; Repeat if any

    ; the following section could be 10% faster if we were able to copy
    ; back to front - unfortunately we are forced to copy strict from
    ; low to high since this function is also used for
    ; memmove and blocks could be overlapping!
    ; {
L2:                ; assert Y = 0
    ldx     ptr3        ; Get the low byte of n
    beq     done        ; something to copy

L3:     lda     (ptr1),Y    ; copy a byte
    sta     (ptr2),Y
    iny
    dex
    bne     L3

    ; }

done    ldx #0
@sp    equ *-1
    rts
.endp


@move    .proc (.word ptr1, ptr2, ptr3) .var

ptr1    = edx
ptr2    = ecx
ptr3    = eax

src    = ptr1
dst    = ptr2
cnt    = ptr3

    cpw ptr2 ptr1
    scs
    jmp @moveu

    stx @sp

; Copy downwards. Adjust the pointers to the end of the memory regions.

    lda     ptr1+1
    add     ptr3+1
    sta     ptr1+1

    lda     ptr2+1
    add     ptr3+1
    sta     ptr2+1

; handle fractions of a page size first

    ldy     ptr3        ; count, low byte
    bne     @entry        ; something to copy?
    beq     PageSizeCopy    ; here like bra...

@copyByte:
    lda     (ptr1),y
    sta     (ptr2),y
@entry:
    dey
    bne     @copyByte
    lda     (ptr1),y    ; copy remaining byte
    sta     (ptr2),y

PageSizeCopy:            ; assert Y = 0
    ldx     ptr3+1        ; number of pages
    beq     done        ; none? -> done

@initBase:
    dec     ptr1+1        ; adjust base...
    dec     ptr2+1
    dey            ; in entry case: 0 -> FF
    lda     (ptr1),y    ; need to copy this 'intro byte'
    sta     (ptr2),y    ; to 'land' later on Y=0! (as a result of the '.repeat'-block!)
    dey            ; FF ->FE
@copyBytes:
    .rept 2            ; Unroll this a bit to make it faster...
    lda     (ptr1),y
    sta     (ptr2),y
    dey
    .endr
@copyEntry:            ; in entry case: 0 -> FF
    bne     @copyBytes
    lda     (ptr1),y    ; Y = 0, copy last byte
    sta     (ptr2),y
    dex            ; one page to copy less
    bne     @initBase    ; still a page to copy?

done    ldx #0
@sp    equ *-1
    rts
.endp
*- TeBe/Madteam
3x Atari 130XE, SDX, CPU 65816, 2x VBXE, 2x IDE Plus rev. C

3

Odp: wydajnościówka w Action!

robiłem też inne testy, i wyszło że zwykła pętla kopiująca musiałaby minimum po 4 bajty na raz kopiować aby prawie dorównać temu kodowi z cc65, w tym stylu

 lda (src),y
 sta (dst),y
 iny
 lda (src),y
 sta (dst),y
 iny
 lda (src),y
 sta (dst),y
 iny
 lda (src),y
 sta (dst),y
 iny
*- TeBe/Madteam
3x Atari 130XE, SDX, CPU 65816, 2x VBXE, 2x IDE Plus rev. C

4

Odp: wydajnościówka w Action!

aż odpalę zliczanie z zegarka, bo nie widzę po rysowaniu w pamięci, żeby to 4x szybciej było - ale dzięki za podpowiedź, muszę zmajstrować tak jak myślałem własną prockę do tego.

Oryginalnie zrobili to tak:

 PROC MoveBlock=*(BYTE POINTER d,s,CARD sz)
[$A085$A186$A284$A0$0$A5A5$16F0$A2B1$A091$C8$F9D0$A1E6$A3E6$A5C6$F1
D0$5F0$A2B1$A091$C8$A4C4$F7D0$60]
$664E P_MOVEBLOCK STA FRET
            STX FRET+1
STY BPTR2
LDY #$00
LDA L00A5
BEQ L6670
LDA (BPTR2),Y  
STA (FRET),Y
INY
BNE L665A
INC FRET+1
INC L00A3
DEC L00A5
BNE L665A
BEQ L6670
L666B       LDA (BPTR2),Y  
STA (FRET),Y
            INY
L6670       CPY L00A4
BNE L666B 
RTS

Ostatnio edytowany przez tooloudtoowide (2020-01-23 19:27:21)

/|\ 400 - 800 Incognito+Supercard - 600XL 64k - 800XL - 1088XEL CF3 - XE GS Ultimate VBXE - SIO2SD - SIDE2 - CA2001 - 1050 - XF551 clone by Zaxon /|\ STE 4MB Ultrasatan /|\ 7800 /|\ PORTFOLIO

5

Odp: wydajnościówka w Action!

tooloudtoowide napisał/a:

Pytanie - czy da się to szybciej w Action?

Bez stosowania szczególnych rozwiązań - nie. Szczególne rozwiązanie to podmienić moveblock na to memcpy z cc65, i będzie tak samo szybko, lub napisać szybką procedurę "blit", która pobierze dodatkowe parametry i mieć możliwość kopiowania prostokąta za jednym wywołaniem.

Trzeba pamiętać, że protokół wywołania procedury w action różni się w zal. od liczby bajtów parametrów: do trzech bajtów parametrów - rejestry  axy. Powyżej - przez komórki pamięci na stronie zerowej (a już nie przez rejestry).

Ostatnio edytowany przez qbahusak (2020-01-24 10:46:35)

6

Odp: wydajnościówka w Action!

dzięki Kuba - z tym prostokątem to czytasz mi w myślach smile

a punkt odniesienia i moje nieśmiałem próbki w Action! tutaj:
http://tooloudtoowide.marcinrusinowski. … vs-action/

Ostatnio edytowany przez tooloudtoowide (2020-01-24 13:45:02)

/|\ 400 - 800 Incognito+Supercard - 600XL 64k - 800XL - 1088XEL CF3 - XE GS Ultimate VBXE - SIO2SD - SIDE2 - CA2001 - 1050 - XF551 clone by Zaxon /|\ STE 4MB Ultrasatan /|\ 7800 /|\ PORTFOLIO