Assembly-kieli ja x86-tason järjestelmäohjelmointi · Oppitunti

Koodin vektorointi SIMD:n avulla

Tutustukaa tekniikoihin, joilla koodin suorituskykyä optimoidaan vektorisoimalla operaatioita SSE/AVX-käskyjen avulla data-rinnakkaisiin tehtäviin.

Oppitunti 3/411 vaihetta

Koodin vektorointi SIMD:n avulla on ilmainen Assembly-kieli ja x86-tason järjestelmäohjelmointi-oppitunti CoddyKitissä. Tämä on oppitunti 3/4. Voit lukea koko oppitunnin alta ilmaiseksi ja harjoitella sen jälkeen käytännössä selaimessa sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla. Oppitunti kuuluu Assembly-kieli ja x86-tason järjestelmäohjelmointi-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. Assembly-kieli ja x86-tason järjestelmäohjelmointi-kurssilla on yhteensä 4 oppituntia.

Vektoroinnin perusteet

Tervetuloa SIMD-aiheisen viimeisen oppitunnin pariin! Olemme tutustuneet SSE/AVX-rekistereihin ja -käskyihin. Nyt kokoamme opit yhteen ja vektorisoimme koodia.

Vektorointi on kääntäjän optimointi tai manuaalinen ohjelmointitekniikka, jossa silmukoita muunnetaan siten, että ne käsittelevät useita data-alkioita samanaikaisesti yhden alkion sijaan.

Miksi vektorisoida? SIMD:n teho

Kuvitellaan, että kaksi lukulistaa lasketaan yhteen. Perinteinen (skalaarinen) tapa laskee yhden parin kerrallaan. SIMD:tä hyödyntävän vektoroinnin avulla voit laskea useita pareja yhdellä käskyllä.

  • Skalaarinen: A[0]+B[0], sitten A[1]+B[1] jne.
  • SIMD: (A[0], A[1], A[2], A[3]) + (B[0], B[1], B[2], B[3]) kaikki kerralla!

Tämä rinnakkainen käsittely nopeuttaa suurten aineistojen toistuvia tehtäviä huomattavasti.

Datan kohdistuksella on merkitystä

Jotta SIMD-suorituskyky olisi optimaalinen, datan tulee olla muistissa kohdistettu. Tämä tarkoittaa, että datalohkon aloitusosoitteen tulee olla vektorikoon monikerta (esimerkiksi 16 tavua SSE:tä ja 32 tavua AVX:ää käytettäessä).

  • Kohdistettu käyttö: Nopeampaa, käyttää esimerkiksi käskyjä MOVAPS.
  • Kohdistamaton käyttö: Hitaampaa, käyttää esimerkiksi käskyjä MOVUPS, koska suorittimen on tehtävä ylimääräistä työtä datan noutamiseksi.

Asianmukainen kohdistus auttaa suoritinta noutamaan datan tehokkaammin ja välttämään suorituskykyhaitat.

Vektoridatan lataaminen

Jotta SIMD-rekistereissä olevaa dataa voidaan käsitellä, se on ensin ladattava muistista. Seuraavassa on yleisiä käskyjä yksinkertaisen tarkkuuden liukuluvuille (PS):

  • MOVAPS XMM0, [mem]: Siirtää 4 kohdistettua yksinkertaisen tarkkuuden liukulukua muistista rekisteriin XMM0.
  • MOVUPS XMM0, [mem]: Siirtää 4 kohdistamatonta yksinkertaisen tarkkuuden liukulukua muistista rekisteriin XMM0.

Käyttäkää aina MOVAPS-käskyä, jos datan kohdistuksen tiedetään olevan kunnossa, jotta suorituskyky olisi parempi.

Vektorilaskutoimitusten suorittaminen

Kun data on SIMD-rekistereissä, voitte suorittaa toimenpiteitä kaikille alkioille samanaikaisesti. Esimerkiksi kahden yksinkertaisen tarkkuuden liukulukuvektorin yhteenlasku:

  • ADDPS XMM0, XMM1: Lisää rekisterin XMM1 vastaavat pakatut yksinkertaisen tarkkuuden liukuluvut rekisteriin XMM0. Tulos tallennetaan rekisteriin XMM0.

Tämä yksi käsky suorittaa neljä erillistä yhteenlaskua rinnakkain!

Vektoritulosten tallentaminen

Kun data on käsitelty SIMD-rekistereissä, tulokset kannattaa tallentaa takaisin muistiin. Kuten lataamisessa, myös tallentamiseen on kohdistettuja ja kohdistamattomia käskyjä:

  • MOVAPS [mem], XMM0: Tallentaa 4 kohdistettua yksinkertaisen tarkkuuden liukulukua rekisteristä XMM0 muistiin.
  • MOVUPS [mem], XMM0: Tallentaa 4 kohdistamatonta yksinkertaisen tarkkuuden liukulukua rekisteristä XMM0 muistiin.

Jos kohdemuisti on kohdistettu, suosikaa jälleen tallentamiseen MOVAPS-käskyä.

Taulukon summan vektorisoiminen

Tarkastellaan yksinkertaista esimerkkiä, jossa kaksi yksinkertaisen tarkkuuden liukulukutaulukkoa lasketaan yhteen SSE-käskyillä. Tämä ohjelma laskee yhteen taulukot array1 ja array2 ja tallentaa tuloksen taulukkoon result.

Käsittelemme silmukan tapaan 4 liukulukua kerrallaan ja siirrämme jokaisella askeleella 16 tavua (4 liukulukua).

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

Muita yleisiä SIMD-toimintoja

ADDPS-käskyn lisäksi SSE/AVX tarjoaa laajan valikoiman käskyjä erilaisiin pakattuihin operaatioihin:

  • SUBPS: Vähentää pakattuja yksinkertaisen tarkkuuden liukulukuja.
  • MULPS: Kertoo pakattuja yksinkertaisen tarkkuuden liukulukuja.
  • DIVPS: Jakaa pakattuja yksinkertaisen tarkkuuden liukulukuja.
  • ANDPS, ORPS, XORPS: Suorittaa bittitasoisia loogisia operaatioita pakatuille liukuluvuille.
  • Vertailukäskyt (esimerkiksi CMPPS): Vertailevat pakattuja liukulukuja.

Oleellista on, että kaikki nämä käskyt käsittelevät useita data-alkioita samanaikaisesti.

Milloin kannattaa vektorisoida

Vektorointi on tehokas optimointi, mutta se ei ole aina tarpeellista tai hyödyllistä. Huomioikaa seuraavat seikat:

  • Suuret aineistot: Tehokkainta silmukoissa, jotka käsittelevät monia alkioita.
  • Toistuvat operaatiot: Ihanteellinen, kun sama operaatio kohdistetaan moniin data-alkioihin.
  • Datan rakenne: Toimii parhaiten yhtenäisen ja kohdistetun datan kanssa.
  • Yleiskustannukset: Pienissä silmukoissa vektorirekisterien alustamisesta voi aiheutua enemmän yleiskustannuksia kuin vektoroinnista saadaan nopeutusta.

Kääntäjät voivat usein vektorisoida koodia automaattisesti, mutta manuaalinen vektorointi antaa tarkemman hallinnan.

Pikatarkistus: vektorointi

Mitkä seuraavista ovat keskeisiä hyötyjä, joita koodin vektorisoimisesta SIMD-käskyillä saadaan?

Kertaus: SIMD:n teho

Hienoa työtä! Olette nyt oppineet käyttämään SSE/AVX-käskyjä koodin vektorisoimiseen.

  • Vektorointi suorittaa operaatioita useille data-alkioille samanaikaisesti.
  • Asianmukainen datan kohdistus on ratkaisevan tärkeää optimaalisen suorituskyvyn saavuttamiseksi.
  • Käskyjä, kuten MOVAPS, ADDPS ja MOVAPS, käytetään pakatun datan lataamiseen, käsittelyyn ja tallentamiseen.
  • Vektorointi on erittäin tehokasta toistuvissa operaatioissa, joita tehdään suurille ja yhtenäisille aineistoille.

Tämän tehokkaan tekniikan avulla voitte saavuttaa merkittäviä suorituskykyparannuksia x86-kokoonpano-ohjelmissanne. Jatkakaa harjoittelua!

Aloita maksutta

Opi Assembly tekoälytuutorin avulla — ilmaiseksi

Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.

Kurssit
12
Oppitunnit
48

Usein kysytyt kysymykset

Onko oppitunti ”Koodin vektorointi SIMD:n avulla” ilmainen?

Kyllä – oppitunnin ”Koodin vektorointi SIMD:n avulla” koko tekstin voi lukea täällä verkossa ilmaiseksi. Jos haluat harjoitella interaktiivisesti sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla sekä avata koko Assembly-kieli ja x86-tason järjestelmäohjelmointi-kurssin, päivitä CoddyKit PROhon. Assembly-kieli ja x86-tason järjestelmäohjelmointi-kurssilla on yhteensä 4 oppituntia.

Mitä opin oppitunnilla ”Koodin vektorointi SIMD:n avulla”?

Tutustukaa tekniikoihin, joilla koodin suorituskykyä optimoidaan vektorisoimalla operaatioita SSE/AVX-käskyjen avulla data-rinnakkaisiin tehtäviin. Harjoittelet Assembly-kieli ja x86-tason järjestelmäohjelmointi-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.

Tarvitsenko kokemusta aloittaakseni Assembly-kieli ja x86-tason järjestelmäohjelmointi-opiskelun?

Aiempi kokemus ei ole tarpeen. CoddyKitin Assembly-kieli ja x86-tason järjestelmäohjelmointi-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 3/4.

Kuinka kauan ”Koodin vektorointi SIMD:n avulla”-oppitunnin suorittaminen kestää?

Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.

Voinko kirjoittaa ja suorittaa koodia tällä Assembly-kieli ja x86-tason järjestelmäohjelmointi-oppitunnilla?

Kyllä. Jokainen Assembly-kieli ja x86-tason järjestelmäohjelmointi-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.

Kaikki tämän kurssin oppitunnit

  1. x87 FPU -ohjelmoinnin perusteet
  2. SSE/AVX-käskyvalikoimien johdanto
  3. Koodin vektorointi SIMD:n avulla
  4. Liukulukujen tarkkuus, pyöristys ja poikkeukset
← Takaisin: Assembly-kieli ja x86-tason järjestelmäohjelmointi