Porównanie procesorów

Z80 jest o niebo lepszym procesorem od 8051 w bardziej zaawansowanych zastosowaniach (wektoryzowane przerwania, łatwiejszy i bardziej rozbudowany język maszynowy). 6502 jest bardzo szybki (przy zegarze 1MHz tak samo szybki jak Z80 4Mhz, a chwilami szybszy od najszybszego 8051-24MHz) co predysponuje go jako sterownik reklamy świetlnej składającej się z kilku tysięcy niezależnie sterowanych LED. W/w sterowniki na Z80 i 6502 były wykonane jako prototypy. Stąd tylko krok do pełnosprawnego urządzenia. Aby zachęcić Czytelników do innych procesorów niż 8051 zrobię małe porównanie kilku procesorów:

PROCEDURA TESTUJĄCA 1 kopiowanie (do 256 bajtów) pamięci:
-----------------------------+-------------------------+-------------------------
 8051                        | 6502                    | Z80
-----------------------------+-------------------------+-------------------------
        mov     R7,#obszar   |        ldx     #obszar  |       ld       b,obszar
        mov     dptr,#źródło |loop:   lda     źródło,x |       ld       ix,źródło
        mov     R0,DPH       |        sta     cel,x    |       ld       iy,cel
        mov     R1,DPL       |        dex              |loop:  ld       a,(ix+0)
        mov     dptr,#cel    |        bne     loop     |       ld       (iy+0),a
        mov     R2,DPH       |        rts              |       inc      ix
        mov     R3,DPL       |                         |       inc      iy
loop:   mov     DPH,R0       |                         |       djnz     loop
        mov     DPL,R1       |                         |       ret
        movx    a,@dptr      |                         |
        inc     dptr         |                         |
        mov     R0,DPH       |                         |
        mov     R1,DPL       |                         |
        mov     R2,DPH       |                         |
        mov     R3,DPL       |                         |
        movx    @dptr,a      |                         |
        inc     dptr         |                         |
        mov     R2,DPH       |                         |
        mov     R3,DPL       |                         |
        djnz    R7,loop      |                         |
        ret                  |                         |
-----------------------------+-------------------------+-------------------------
długość kodu: 37 bajtów      |               12 bajtów |                23 bajty
-----------------------------+-------------------------+-------------------------

UWAGA! 
        Z80 posiada rozkazy
        przesłania blokowego
        LDIR i LDDR

UWAGA! Jestem stosunkowo młodym koderem na 8051 (wychowałem się na 6502). Z80 znam trochę lepiej.Dlatego procedury mogą być kiepskie. Jeśli znajdzie się Czytelnik, który napisze szybszą procedurę proszę o kontakt. Zmierzę czas wykonywania procedury, a o wynikach zawiadomię na łamach EDW. Wynik testu programu polegający na 512-krotnym powtórzeniu go i pomiarze czasu. Obszar do skopiowania 255 bajtów.
        procesor     częst. zegara/     teoretyczny czas czas wykonania	przy max. częst. zegara
  Z80 (rozkaz LDIR)       4 MHz	0.70 sek.        8MHz  0.35 sek.
  6502                    1 MHz	1.86 sek.        4MHz  0.46 sek.
  Z80                     4 MHz	2.30 sek.        8MHz  115 sek.
  8051                   11 MHz	3.90 sek.       24MHz  1.95 sek.
  68040                  40 MHz	0.046 sek

Pozwoliłem sobie porównać czas wykonywania operacji przez Motorollę 68040 40MHz, wynik 0.046 sek. Jak widać 32bity, pamięć CACHE, architektura RISC i dobry język maszynowy dają dobre efekty. Nie miałem okazji porównać 68040 z PENTIUM, a jestem ciekaw wyniku. Dla ciekawskich kod programu kopiującego dane (max. 4GB):
licz:   move.l  #obszar,d0
        movea.l #źródło,a0
        movea.l #cel,a1
loop:   move.b  (a1)+,(A0)+
        dbf     d0,loop
        rts

PROCEDURA TESTUJĄCA 2 odliczanie od 1999 do 0000 w kodzie BCD,
liczniki w pamięci RAM:
--------------------------------+-----------------------+-------------------------
 8051                           | 6502                  | Z80
--------------------------------+-----------------------+-------------------------
        mov     counter_h,#$19  |       sed             |       ld      hl,counter_l
        mov     counter_l,#$99  |       lda  #$19       |       ld      a,$19
loop:   mov     a,counter_l     |       sta  counter_hl |       ld      (hl),a
        acall   decacc          |       lda  #$99       |       ld      a,$99
        mov     counter_l,a     |       sta  counter_l  |       inc     hl
        cjne    a,#0,loop       |       loop sec        |       ld      (hl),a
        mov     a,counter_h     |       lda  counter_l  |loop:  ld      hl,counter_l
        acall   decacc          |       sbc  #1         |       ld      a,(hl)
        mov     counter_h,a     |       sta  counter_l  |       sub     1
        cjne    a,#0,loop       |       bne  loop       |       daa
        ret                     |       sec             |       ld      (hl),a
                                |       lda  counter_h  |       cp      0
                                |       sbc  #1         |       jr      nz,loop
decacc: cjne    a,#0,niero      |       sta  counter_h  |       inc     hl
        mov     a,#99           |       bne  loop       |       ld      a,(hl)
        ret                     |       rts             |       sub     1
niero:  clr     C               |                       |       daa
        subb    a,#1            |                       |       ld      (hl),a
        push    ACC             |                       |       cp      0
        anl     a,#$f           |                       |       jr      nz,loop
        cjne    a,#$f,nie0F     |                       |       ret
        pop     ACC             |                       |
        anl     a,#$f0          |                       |
        orl     a,#9            |                       |
        ret                     |                       |
nie0F   pop     ACC             |                       |
        ret                     |                       |
--------------------------------+-----------------------+-------------------------
długość kodu: 61 (38+23decacc)  |        34 bajty       |           33 bajty
              69 (42+23 decacc) |                       |
              dla liczników     |                       |
              w zewnętrznej RAM |                       |
--------------------------------+-----------------------+-------------------------

UWAGA! W 8051 korekcja dziesiętna działa tylko przy dodawaniu, stąd dodatkowy podprogram DECACC. Wynik testu programu polegający na 256-krotnym powtórzeniu go i pomiarze czasu.
  procesor  częst.zegara    czas wykonania      teoretyczny czas przy max. częst. zegara
  6502      1 MHz           6.47 sek.           4MHz 1.67sek.
  Z80       4 MHz           6.60 sek.           8MHz 3.30 sek.
  8051     11 MHz           10.60 sek.          24MHz 5.30 sek.   
  8051 (zewnętrzna)11 MHz   13.00 sek.          24MHz 6.50 sek.

Proszę przy analizie tabelki pamiętać, że przy umieszczeniu danych w zewnętrznej pamięci programu, w przypadku 8051 należałoby zamienić rozkazy:
        mov    a,counter       na:      mov     counter,a 
        mov    dptr,#counter_l na:      movx    a,@dptr
        mov    dptr,#counter_l na:      movx    @dptr,a

Po takiej zmianie czas 256 krotnego wykonania programu zwiększył się do 13 sek.

Warto wspomieć, że nie darzę sympatią 8051 (najbardziej lubię 6502 i 680x0). Brakuje mu takich rozkazów jak:
 DEC    DPTR    - zmiejszenie wskaźnika dptr,
 CMP            - porównanie rejestrów, komórek pamięci,
 MOVC   A,@DPTR - przesłanie z pamięci danych (istnieje MOVC  A,@ADPTR i najczęściej wymagane jest zerowanie ACC)

A teraz trochę MIPS-ów:
Z80      4MHz   1.00
Z80      8MHz   2.00
8051    12MHz   0.50
8051    24MHz   1.00
6502     1MHz   0.25
6502     4MHz   1.00
68040   40MHz  30.40

UWAGA! Wartości w tabeli są czysto teoretyczne, wynikające z obliczeń matematycznych, dlatego mogą odbiegać od rzeczywistości. Jak widać MIPS-y, megaherce, nie oddają rzeczywistej szybkości procesora. Czytelnicy sami ocenią kod, którego procesora jest przejrzystrzy, krótszy, który procesor wykonuje swoje zadanie najszybciej. Tak na marginesie to byłem zaskoczony dużą szybkością Z80. Dotychczas tego typu porównania robiłem teoretycznie w oparciu o literaturę i katalogi. Napisanie tego artykułu zmusiło mnie do wykonania testów w praktyce. Jak widać wyniki mogą być zaskakujące.

Literatura:
1) Układy Mikroprocesorowe Z80 Konrad Feryna i Marek Mizeracki WKŁ Warszawa 1989r.
2) Mikroprocesor 6502 i jego rodzinaHenryk Kruszyński i Krzystof Kulpa NOT SIGMA Warszawa 1989r.
3) Podstawy programowania mikrokontrolera 8051 Piotr Gałka i Paweł Gałka ZNI MIKOM Warszawa 1995r.

Sławomir Skrzyński