Quantcast

Da li je vreme da se uci aarch64 asembler?

bmaxa

Veoma poznat
Poruka
14.235
Ja sam ljubitelj x86 asemblera, iako u praksi nemam primene osim sa hobi projekte,
ali asembler je nesto sto mislim da svaki programer mora znati ako sebe hoce
da zove programerom. Tu je znaci ucenje procesora i njegove specificnosti.
Dakle ono lako je sad iskompajlirati, ali napravi nesto i znaj nesto.
ARM64 se probio na scenu, pa mozda sad osim sto ljudi znaju x86,
mozda ce on za koju godinu biti bas aktuelan kao sada x86?
 

bmaxa

Veoma poznat
Poruka
14.235
Lep primer za ucenje ARM64(aarch64) asemblera.
Asembler koji se koristi je takodje moj omiljeni flat assembler, u sledecoj generaciji koja se ne vezuje za arhitekturu
nego se instrukcije za odrejenu arhitekturu inkluduju.
https://github.com/lucabrivio/asmFish-fasmg

Introduction​


Welcome to the project of translating Stockfish into assembly language. This project now uses the new assembler engine fasmg from Tomasz Grysztar. The includes in arm/includes/ or x86/include/ contain instruction and formatting macros for the four popular targets in the Building section. The hello world examples in these directories should provide enough to grasp the syntax.
 

bmaxa

Veoma poznat
Poruka
14.235
Zbog ovoga sam kupio macbook,da se pripremim za budućnost :)
Evo ga hello world na aarch64 mac OS-u, asembler je GNU gas, jedini koliko znam izbor za ARM:
Kod:
msg:
    .ascii        "Hello, ARM64!\n"
len = . - msg

.globl _main ; osx linker traži ovaj simbol za ulaz
.align 4        ; f-je moraju na 4 bajta da se alajnuju

_main:

    mov     x0,#1 ; standardni izlaz, stdout
    adr     x1,msg ; adresa poruke
    mov     x2,len    ; duzina
    mov     x16, #4    ; syscall broj 4 je write
    svc     #0        ; poziv sistemskog servisa

   mov     x0, #0      ; povratni kod
   mov     x16, #1     ; 1 je izlaz
   svc     #0   ; jasno
; kraj
i idemo:
Kod:
bmaxa@Branimirs-MacBook-Air assembler % as hello.s -o hello.o                                                                     
bmaxa@Branimirs-MacBook-Air assembler % ld -o hello hello.o -lSystem -L/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib
bmaxa@Branimirs-MacBook-Air assembler % ./hello
Hello, ARM64!

I to bi bilo to za početak :)
 

bmaxa

Veoma poznat
Poruka
14.235
A sada to isto ali sa kooperacijom sa C bibliotekom:
Kod:
        .text
msg:
        .ascii "Zdravo Svete!\0"
        .globl _main
        .align 4
_main:
        stp     x29, x30, [sp, -16]!
        adr     x0, msg
        mov     x29, sp
        bl      _puts
        ldp     x29, x30, [sp], 16
        mov     x0, 0
        ret
x29 je frejm, a x30 link pointer, tj onaj koji cuva return adresu. Ova dva se moraju
sacuvati i to se radi na pocetku sa stp instrukcijom koja ih smesta na stek.
potom se frejm podesi da pokauzuje na vrh steka da ih puts ne pregazi.
x0 drzi pointer na string za puts. I poziv f-je sledi. Nakon povratka vraca
se vrednost x29 i x30 registara. potom sledi izlaz sa ret. (ret koristi adresu
u x30 a x29 je frejm koji je nasetovala pozivna f-ja. I to je to.

Kod:
bmaxa@Branimirs-MacBook-Air assembler % as helloc.s -o hello.o                                                                    
bmaxa@Branimirs-MacBook-Air assembler % ld -o hello hello.o -lSystem -L/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib
bmaxa@Branimirs-MacBook-Air assembler % ./hello
Toliko za danas :)
 

bmaxa

Veoma poznat
Poruka
14.235
Sad sam krenuo da pretabam, merge i radix sort listi u asm_u koji su trenutno za x86.
Zahvaljujuci rozeti tj jit-u koji prevodi x86 kod u ARM kod mogu ovo da vozim na Mac-u.
Evo recimo 2700x isti program i na Mac-u.
Kod:
list radix elapsed 1.071881 seconds
list merge elapsed 0.308731 seconds
size of node 12, length 1000000
a gle na Macu:
Kod:
list radix elapsed 0.090691 seconds
list merge elapsed 0.048341 seconds
size of node 16, length 1000000

I jednom i drugom milion noda staje u cache, ali je M1 drasticno brzi :P
Kad pretabam objavim.
 

bmaxa

Veoma poznat
Poruka
14.235
Evo ga full blown asm program za M1, sto je retkost naci:P
Zezao sam se najvise sa stekom, zato sto ARM ne da nonaligned pristup steku, za razliku
od x86, pa sam tu imao pretumbacija. Osim toga nasao sam lep nacin da se meri vreme
izvrsavanja a to je mrs instrukcija koja cita sistemske registre od kojih su dva interesantna:
cntfrq_el0 koji daje frekvenciju sa kojom se deli takt tako da se dobiju sekunde i drugi
je CNTPCT_EL0 koji daje sam brojac.
Progi je ovde kao sto sam obecao: https://github.com/bmaxa/asmsort
 

bmaxa

Veoma poznat
Poruka
14.235
A sada primer koriscenja SIMD instrukcija.
Kod:
    .text
    .globl _main
    .align 4
    .arch armv8a
_main:
    stp    x29, x30, [sp, -16]!
    adrp x1,simd1@PAGE
    ldr q0,[x1,simd1@PAGEOFF]
    adrp x2,simd2@PAGE
    ldr q1,[x2,simd2@PAGEOFF]
    add.4s v0,v1,v0
    sub sp,sp,32
    mov.s w8,v0[0]
    str x8,[sp]
    mov.s w8,v0[1]
    str x8,[sp,8]
    mov.s w8,v0[2]
    str x8,[sp,16]
    mov.s w8,v0[3]
    str x8,[sp,24]
    adrp x0,msgsimd@PAGE
    add  x0,x0,msgsimd@PAGEOFF
    bl _printf
    add sp,sp,32
    ldp    x29, x30, [sp], 16
    eor     x0,x0,x0
    ret
    .data
msgsimd:
    .asciz "%d %d %d %d!\n"
.align 16
simd1:
.long 1
.long 2
.long 3
.long 4
simd2:
.long 10
.long 20
.long 30
.long 40

E sad na ARM postoji SIMD koji se zove Neon i najblizi je SSE2 na x86. Dakle koriscenje je prilicno slicno
sa time da su naravno instrukcije drugacije.
1. ucitavanje iz memorije. Kada se ovo radi koristi se oznaka q0-31 za registar, dakle
ldr q0,[x1,simd1@PAGEOFF] ucitava u registar q0 4 32 bitna inta.
2. operacija
add.4s v0,v1,v0 oznacava celobrojno sabiranje 4 worda (word je 32 bitni na ARM za razliku od x86 gde je to dword).
v0 i v1 su oznake da se radi o vektorskoj operaciji. Ovo isto moze da se napise i kao add v0.4s,v1.4s,v0.4s sto je verboznije.
Potom zelimo da isprintamo rezultat.
mov.s w8,v0[0] znaci extraktuj prvi element iz vektora, velicine word i smesti u 32-bitni int registar w8.
printf na macOS u x0 uzima format string, a parametri idu na stek sa leva na desno, tj odozdo na gore.
i to bi bilo to.
 
Poslednja izmena:

bmaxa

Veoma poznat
Poruka
14.235
I kao sto se dalo pretpostaviti:
Kod:
.L1main:
    cmp x20,20
    blt lo
    advance A
    advance B
    advance C
    advance D
    advance E
    advance F
    advance G
    advance H
    advance I
    advance J
    advance 01
    advance 02
    advance 03
    advance 04
    advance 05
    advance 06
    advance 07
    advance 08
    advance 09
    advance 10
    subs x20,x20,20
    bgt .L1main
    b Lskip
lo:
    advance K
    subs x20,x20,1
    bgt lo
Lskip:
Ovo mi je dalo 10% na performansama :P
 

Top
  Blokirali ste reklame
Dragi prijatelju, nemojte da blokirate reklame - isključite Ad Blocker na Forumu, jer će tako mesto vaših susreta na Krstarici ostati besplatno za korišćenje.