Assembly-språk og x86-programmering på lavt systemnivå · leksjon

Vektorisering av kode med SIMD

Oppdag teknikker for å optimalisere kodeytelsen ved å vektorisere operasjoner med SSE-/AVX-instruksjoner for dataparallelle oppgaver.

Leksjon 3 av 411 trinn

Vektorisering av kode med SIMD er en gratis leksjon i Assembly-språk og x86-programmering på lavt systemnivå på CoddyKit. Dette er leksjon 3 av 4. Du kan lese hele leksjonen gratis nedenfor – og deretter øve praktisk i nettleseren med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i Assembly-språk og x86-programmering på lavt systemnivå, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i Assembly-språk og x86-programmering på lavt systemnivå inneholder totalt 4 leksjoner.

Introduksjon til vektorisering

Velkommen til den siste leksjonen om SIMD! Vi har lært om SSE/AVX-registre og instruksjoner. Nå skal vi sette alt sammen for å vektorisere kode.

Vektorisering er en kompilatoroptimalisering eller en manuell kodeteknikk som omformer løkker slik at de utfører operasjoner på flere dataelementer samtidig, i stedet for ett om gangen.

Hvorfor vektorisere? SIMD-kraft

Se for deg at du legger sammen to lister med tall. En tradisjonell (skalar) tilnærming legger sammen ett par om gangen. Vektorisering med SIMD lar deg legge sammen flere par i én enkelt instruksjon.

  • Skalar: A[0]+B[0], deretter A[1]+B[1], og så videre.
  • SIMD: (A[0], A[1], A[2], A[3]) + (B[0], B[1], B[2], B[3]) – alt på én gang!

Denne parallelle behandlingen gjør repetitive oppgaver på store datasett betydelig raskere.

Datajustering er viktig

For optimal SIMD-ytelse bør dataene være justert i minnet. Det betyr at startadressen til datablokken bør være et multiplum av vektorstørrelsen (for eksempel 16 byte for SSE og 32 byte for AVX).

  • Justert tilgang: Raskere, bruker instruksjoner som MOVAPS.
  • Ujustert tilgang: Saktere, bruker instruksjoner som MOVUPS, siden CPU-en må utføre ekstra arbeid for å hente dataene.

Riktig justering hjelper CPU-en med å hente data mer effektivt og unngå ytelsestap.

Laste inn vektordata

For å arbeide med data i SIMD-registre må du først laste dem inn fra minnet. Her er vanlige instruksjoner for flyttall med enkel presisjon (PS):

  • MOVAPS XMM0, [mem]: Flytter 4 justerte flyttall med enkel presisjon fra minnet til XMM0.
  • MOVUPS XMM0, [mem]: Flytter 4 ujusterte flyttall med enkel presisjon fra minnet til XMM0.

Bruk alltid MOVAPS når dataene garantert er justert, for å oppnå bedre ytelse.

Utføre vektormatematikk

Når dataene er i SIMD-registre, kan du utføre operasjoner på alle elementene samtidig. For eksempel kan du legge sammen to vektorer med flyttall med enkel presisjon:

  • ADDPS XMM0, XMM1: Legger de tilsvarende pakkede flyttallene med enkel presisjon i XMM1 til XMM0. Resultatet lagres i XMM0.

Denne ene instruksjonen utfører fire separate addisjoner parallelt!

Lagre vektorresultater

Etter at dataene er behandlet i SIMD-registre, vil du lagre resultatene tilbake i minnet. På samme måte som ved innlasting finnes det lagringsinstruksjoner for både justerte og ujusterte data:

  • MOVAPS [mem], XMM0: Lagrer 4 justerte flyttall med enkel presisjon fra XMM0 til minnet.
  • MOVUPS [mem], XMM0: Lagrer 4 ujusterte flyttall med enkel presisjon fra XMM0 til minnet.

Prioriter igjen MOVAPS ved lagring hvis målminnet er justert.

Vektorisere en arraysummering

La oss se på et enkelt eksempel på hvordan to arrayer med flyttall med enkel presisjon legges sammen ved hjelp av SSE-instruksjoner. Dette programmet legger sammen array1 og array2 og lagrer resultatet i result.

Vi behandler 4 flyttall om gangen i en løkkelignende prosess og flytter 16 byte (4 flyttall) for hvert trinn.

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 vanlige SIMD-operasjoner

I tillegg til ADDPS tilbyr SSE/AVX et bredt utvalg av instruksjoner for ulike pakkede operasjoner:

  • SUBPS: Trekker fra pakkede flyttall med enkel presisjon.
  • MULPS: Multipliserer pakkede flyttall med enkel presisjon.
  • DIVPS: Dividerer pakkede flyttall med enkel presisjon.
  • ANDPS, ORPS, XORPS: Bitvise logiske operasjoner på pakkede flyttall.
  • Sammenligningsinstruksjoner (for eksempel CMPPS): Sammenligner pakkede flyttall.

Poenget er at alle opererer på flere dataelementer samtidig.

Når bør du vektorisere

Vektorisering er en kraftig optimalisering, men er ikke alltid nødvendig eller fordelaktig. Vurder følgende:

  • Store datasett: Mest effektivt for løkker som behandler mange elementer.
  • Repetitive operasjoner: Ideelt for identiske operasjoner som brukes på mange dataelementer.
  • Datalayout: Fungerer best med sammenhengende, justerte data.
  • Overhead: Små løkker kan få større overhead ved oppsett av vektorregistre enn ytelsesøkningen de gir.

Kompilatorer kan ofte vektorisere automatisk, men manuell vektorisering gir deg detaljert kontroll.

Hurtigsjekk: Vektorisering

Hvilke av følgende er viktige fordeler ved å vektorisere kode ved hjelp av SIMD-instruksjoner?

Oppsummering: SIMD-kraft

Godt jobbet! Nå har du lært hvordan du bruker SSE/AVX-instruksjoner til å vektorisere koden din.

  • Vektorisering utfører operasjoner på flere dataelementer samtidig.
  • Riktig justering av data er avgjørende for optimal ytelse.
  • Instruksjoner som MOVAPS, ADDPS og MOVAPS brukes til å laste inn, behandle og lagre pakkede data.
  • Vektorisering er svært effektivt for repetitive operasjoner på store, sammenhengende datasett.

Denne kraftige teknikken lar deg oppnå betydelige ytelsesforbedringer i x86-assemblyprogrammene dine. Fortsett å øve!

Gratis å komme i gang

Lær deg Assembly med en AI-veileder – gratis

Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.

Kurs
12
Leksjoner
48

Ofte stilte spørsmål

Er leksjonen «Vektorisering av kode med SIMD» gratis?

Ja – hele teksten i «Vektorisering av kode med SIMD» er gratis å lese her på nettet. For å øve interaktivt med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt, og for å låse opp resten av Assembly-språk og x86-programmering på lavt systemnivå-kurset, kan du oppgradere til CoddyKit PRO. Kurset i Assembly-språk og x86-programmering på lavt systemnivå inneholder totalt 4 leksjoner.

Hva lærer jeg i «Vektorisering av kode med SIMD»?

Oppdag teknikker for å optimalisere kodeytelsen ved å vektorisere operasjoner med SSE-/AVX-instruksjoner for dataparallelle oppgaver. Du øver på Assembly-språk og x86-programmering på lavt systemnivå med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.

Trenger jeg erfaring for å begynne med Assembly-språk og x86-programmering på lavt systemnivå?

Ingen tidligere erfaring er nødvendig. Assembly-språk og x86-programmering på lavt systemnivå på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 3 av 4.

Hvor lang tid tar leksjonen «Vektorisering av kode med SIMD»?

De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.

Kan jeg skrive og kjøre kode i denne Assembly-språk og x86-programmering på lavt systemnivå-leksjonen?

Ja. Alle Assembly-språk og x86-programmering på lavt systemnivå-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.

Alle leksjonene i dette kurset

  1. Grunnleggende x87 FPU-programmering
  2. Introduksjon til SSE-/AVX-instruksjonssett
  3. Vektorisering av kode med SIMD
  4. Presisjon, avrunding og unntak for flyttall
← Tilbake til Assembly-språk og x86-programmering på lavt systemnivå