Assembly-sprog og x86-systemprogrammering på lavt niveau · Lektion

Vektorisering af kode med SIMD

Opdag teknikker til optimering af kodens ydeevne ved at vektorisere operationer med SSE/AVX-instruktioner til dataparallelle opgaver.

Lektion 3 af 411 trin

Vektorisering af kode med SIMD er en gratis Assembly-sprog og x86-systemprogrammering på lavt niveau-lektion på CoddyKit. Dette er lektion 3 af 4. Du kan læse hele lektionen gratis nedenfor — og derefter øve dig praktisk i browseren med en indbygget kodeeditor og en AI-vejleder, der er tilgængelig døgnet rundt. Den er en del af læringsforløbet i Assembly-sprog og x86-systemprogrammering på lavt niveau, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. Assembly-sprog og x86-systemprogrammering på lavt niveau-kurset indeholder 4 lektioner i alt.

Introduktion til vektorisering

Velkommen til den sidste lektion om SIMD! Vi har lært om SSE/AVX-registre og instruktioner. Nu samler vi det hele for at vektorisere kode.

Vektorisering er en kompilatoroptimering eller en manuel kodningsteknik, der omdanner løkker, så de udfører operationer på flere dataelementer samtidigt i stedet for ét ad gangen.

Hvorfor vektorisere? SIMD-kraft

Forestil dig, at du lægger to lister med tal sammen. En traditionel (skalar) tilgang lægger ét par sammen ad gangen. Med vektorisering ved hjælp af SIMD kan du lægge flere par sammen i én instruktion.

  • Skalar: A[0]+B[0], derefter A[1]+B[1] osv.
  • SIMD: (A[0], A[1], A[2], A[3]) + (B[0], B[1], B[2], B[3]) på én gang!

Denne parallelle behandling gør gentagne opgaver på store datasæt markant hurtigere.

Datajustering er vigtig

For at opnå optimal SIMD-ydeevne bør dine data være justeret i hukommelsen. Det betyder, at startadressen for din datablok skal være et multiplum af vektorstørrelsen (f.eks. 16 byte for SSE og 32 byte for AVX).

  • Justeret adgang: Hurtigere og bruger instruktioner som MOVAPS.
  • Ujusteret adgang: Langsommere og bruger instruktioner som MOVUPS, fordi CPU'en skal udføre ekstra arbejde for at hente dataene.

Korrekt justering hjælper CPU'en med at hente data mere effektivt og undgå ydeevnestraffe.

Indlæsning af vektordata

For at arbejde med data i SIMD-registre skal du først indlæse dem fra hukommelsen. Her er almindelige instruktioner til flydende tal med enkelt præcision (PS):

  • MOVAPS XMM0, [mem]: Flytter 4 justerede flydende tal med enkelt præcision fra hukommelsen til XMM0.
  • MOVUPS XMM0, [mem]: Flytter 4 ujusterede flydende tal med enkelt præcision fra hukommelsen til XMM0.

Prøv altid at bruge MOVAPS, hvis dine data med sikkerhed er justeret, for at opnå bedre ydeevne.

Udførelse af vektorberegninger

Når dataene er i SIMD-registre, kan du udføre operationer på alle elementer samtidigt. Hvis du f.eks. vil lægge to vektorer med flydende tal med enkelt præcision sammen:

  • ADDPS XMM0, XMM1: Lægger de tilsvarende pakkede flydende tal med enkelt præcision i XMM1 til XMM0. Resultatet gemmes i XMM0.

Denne ene instruktion udfører fire separate additioner parallelt!

Lagring af vektorresultater

Efter behandling af data i SIMD-registre vil du gemme resultaterne tilbage i hukommelsen. Ligesom ved indlæsning findes der instruktioner til lagring af både justerede og ujusterede data:

  • MOVAPS [mem], XMM0: Gemmer 4 justerede flydende tal med enkelt præcision fra XMM0 i hukommelsen.
  • MOVUPS [mem], XMM0: Gemmer 4 ujusterede flydende tal med enkelt præcision fra XMM0 i hukommelsen.

Prioritér igen MOVAPS ved lagring, hvis destinationshukommelsen er justeret.

Vektorisering af en array-sum

Lad os se på et enkelt eksempel på, hvordan to arrays med flydende tal med enkelt præcision lægges sammen ved hjælp af SSE-instruktioner. Dette program lægger array1 og array2 sammen og gemmer resultatet i result.

Vi behandler 4 flydende tal ad gangen i en løkkelignende struktur og flytter 16 byte (4 flydende tal) pr. trin.

section .data
    ; Define 8 single-precision floats (4 bytes each), aligned to 16 bytes
    ; 'dd' defines a doubleword (4 bytes), suitable for floats
    array1: align 16
        dd 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0
    array2: align 16
        dd 8.0, 7.0, 6.0, 5.0, 4.0, 3.0, 2.0, 1.0
    result: align 16
        dd 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0

section .text
    global _start

_start:
    ; Process the first 4 floats (16 bytes)
    movaps xmm0, [array1]    ; Load 1.0, 2.0, 3.0, 4.0 into xmm0
    movaps xmm1, [array2]    ; Load 8.0, 7.0, 6.0, 5.0 into xmm1
    addps  xmm0, xmm1        ; Add packed floats: (9.0, 9.0, 9.0, 9.0)
    movaps [result], xmm0    ; Store result to result[0-3]

    ; Process the next 4 floats (16 bytes offset)
    movaps xmm0, [array1 + 16] ; Load 5.0, 6.0, 7.0, 8.0 into xmm0
    movaps xmm1, [array2 + 16] ; Load 4.0, 3.0, 2.0, 1.0 into xmm1
    addps  xmm0, xmm1        ; Add packed floats: (9.0, 9.0, 9.0, 9.0)
    movaps [result + 16], xmm0 ; Store result to result[4-7]

    ; Exit program (Linux specific system call)
    mov eax, 1               ; sys_exit system call number
    xor ebx, ebx             ; exit code 0
    int 0x80                 ; Call kernel

Andre almindelige SIMD-operationer

Ud over ADDPS tilbyder SSE/AVX en lang række instruktioner til forskellige pakkede operationer:

  • SUBPS: Subtraherer pakkede flydende tal med enkelt præcision.
  • MULPS: Multiplicerer pakkede flydende tal med enkelt præcision.
  • DIVPS: Dividerer pakkede flydende tal med enkelt præcision.
  • ANDPS, ORPS, XORPS: Bitvise logiske operationer på pakkede flydende tal.
  • Sammenligningsinstruktioner (f.eks. CMPPS): Sammenligner pakkede flydende tal.

Det afgørende er, at de alle arbejder på flere dataelementer samtidigt.

Hvornår skal du vektorisere

Vektorisering er en effektiv optimering, men den er ikke altid nødvendig eller fordelagtig. Overvej følgende:

  • Store datasæt: Mest effektivt for løkker, der behandler mange elementer.
  • Gentagne operationer: Ideelt til identiske operationer, der anvendes på mange dataelementer.
  • Datalayout: Fungerer bedst med sammenhængende, justerede data.
  • Overhead: Små løkker kan medføre mere overhead ved opsætning af vektorregistre, end den opnåede hastighedsforbedring kan opveje.

Kompilatorer kan ofte autovektorisere, men manuel vektorisering giver dig finmasket kontrol.

Hurtigt tjek: Vektorisering

Hvilke af følgende er vigtige fordele ved at vektorisere kode ved hjælp af SIMD-instruktioner?

Opsummering: SIMD-kraft

Godt gået! Du har nu lært at anvende SSE/AVX-instruktioner til at vektorisere din kode.

  • Vektorisering udfører operationer på flere dataelementer samtidigt.
  • Korrekt datajustering er afgørende for optimal ydeevne.
  • Instruktioner som MOVAPS, ADDPS og MOVAPS bruges til at indlæse, behandle og gemme pakkede data.
  • Vektorisering er særligt effektiv til gentagne operationer på store, sammenhængende datasæt.

Denne effektive teknik gør det muligt at opnå betydelige ydeevneforbedringer i dine x86-assemblyprogrammer. Bliv ved med at øve dig!

Gratis at komme i gang

Lær Assembly med en AI-underviser — gratis

Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.

Kurser
12
Lektioner
48

Ofte stillede spørgsmål

Er lektionen “Vektorisering af kode med SIMD” gratis?

Ja — hele teksten til “Vektorisering af kode med SIMD” kan læses gratis her på nettet. Hvis du vil øve dig interaktivt med en indbygget kodeeditor og en AI-vejleder døgnet rundt og få adgang til resten af Assembly-sprog og x86-systemprogrammering på lavt niveau-kurset, skal du opgradere til CoddyKit PRO. Assembly-sprog og x86-systemprogrammering på lavt niveau-kurset indeholder 4 lektioner i alt.

Hvad lærer jeg i “Vektorisering af kode med SIMD”?

Opdag teknikker til optimering af kodens ydeevne ved at vektorisere operationer med SSE/AVX-instruktioner til dataparallelle opgaver. Du øver dig i Assembly-sprog og x86-systemprogrammering på lavt niveau med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.

Skal jeg have erfaring for at begynde på Assembly-sprog og x86-systemprogrammering på lavt niveau?

Der kræves ingen tidligere erfaring. Assembly-sprog og x86-systemprogrammering på lavt niveau på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 3 af 4.

Hvor lang tid tager lektionen “Vektorisering af kode med SIMD”?

De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.

Kan jeg skrive og køre kode i denne Assembly-sprog og x86-systemprogrammering på lavt niveau-lektion?

Ja. Alle Assembly-sprog og x86-systemprogrammering på lavt niveau-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.

Alle lektioner i dette kursus

  1. Grundlæggende x87 FPU-programmering
  2. Introduktion til SSE/AVX-instruktionssæt
  3. Vektorisering af kode med SIMD
  4. Præcision, afrunding og undtagelser ved flydende tal
← Tilbage til Assembly-sprog og x86-systemprogrammering på lavt niveau