WebHU - Programozási kérdések és válaszok

A CUDA-ban mi az a memóriaegyesítés, és hogyan érhető el?

Mi az "egyesítés" a CUDA globális memóriatranzakciójában? Még azután sem értettem, hogy átnéztem a CUDA útmutatómat. Hogyan kell csinálni? A CUDA programozási útmutató mátrixpéldájában a mátrix soronkénti elérését "összevontnak" nevezzük, vagy a col.. by col.. összevonásnak nevezzük? Melyik a helyes és miért?


Válaszok:


1

Valószínűleg ez az információ csak az 1.x vagy a cuda 2.0 számítási kapacitásra vonatkozik. Az újabb architektúrák és a cuda 3.0 kifinomultabb globális memória-hozzáféréssel rendelkeznek, és valójában az „összevont globális terhelések” még csak nincsenek is profilozva ezekhez a chipekhez.

Ez a logika a megosztott memóriára is alkalmazható a banki konfliktusok elkerülése érdekében.


Az egyesített memória-tranzakció olyan, amelyben a fél-tekervényben lévő összes szál egyszerre éri el a globális memóriát. Ez túl egyszerű, de a helyes módja annak, hogy az egymást követő szálak egymás utáni memóriacímeket érjenek el.

Tehát, ha a 0., 1., 2. és 3. szál a 0x0, 0x4, 0x8 és 0xc globális memóriát olvassa, akkor ennek egy egyesített olvasásnak kell lennie.

Egy mátrixos példában ne feledje, hogy azt szeretné, hogy a mátrix lineárisan legyen a memóriában. Ezt tetszés szerint megteheti, és a memória-hozzáférésnek tükröznie kell a mátrix elrendezését. Tehát az alábbi 3x4-es mátrix

0 1 2 3
4 5 6 7
8 9 a b

sorról sorra meg lehet tenni, így, így (r,c) a memóriába képezi le (r*4 + c)

0 1 2 3 4 5 6 7 8 9 a b

Tegyük fel, hogy egyszer el kell érnie az elemet, és négy szála van. Melyik elemhez mely szálak lesznek felhasználva? Valószínűleg akár

thread 0:  0, 1, 2
thread 1:  3, 4, 5
thread 2:  6, 7, 8
thread 3:  9, a, b

or

thread 0:  0, 4, 8
thread 1:  1, 5, 9
thread 2:  2, 6, a
thread 3:  3, 7, b

Melyik a jobb? Melyik eredményez egyesített olvasást, és melyik nem?

Akárhogy is, minden szál három hozzáférést biztosít. Nézzük meg az első hozzáférést, és nézzük meg, hogy a szálak egymás után hozzáférnek-e a memóriához. Az első opcióban az első hozzáférés 0, 3, 6, 9. Nem egymást követő, nem egyesült. A második lehetőség: 0, 1, 2, 3. Egymás után! Összeállt! Hurrá!

A legjobb módszer valószínűleg az, ha megírja a kernelt, majd profilba állítja, hogy megnézze, vannak-e nem egyesített globális betöltései és tárolói.

18.02.2011
  • Köszönöm a magyarázatot, hogy melyik szál melyik elemhez fér hozzá. Jelenleg az első lehetőségem van (thread 0: 0, 1, 2 etc...), ezért most jobbat keresek :-) 19.05.2011
  • @jmilloy - Azt szeretném kérdezni, hogyan lehet profilt készíteni a kernelről, hogy lássa a nem egyesített globális betöltéseket és tárolásokat. 13.12.2013
  • @muradin Használhatod a Visual Profiler-t? developer.nvidia.com/nvidia-visual-profiler 13.12.2013
  • @jmilloy - Mivel nem grafikus környezetben dolgozom, parancssori módban kerestem és találtam az nvprof-ot. de amikor le akartam futtatni, hiba történt: nvprof nem tudta betölteni a libcuda.so.1-et, nincs ilyen fájl vagy könyvtár! tudod miért? 13.12.2013
  • @jmilloy:Szia , nagyon szép példa!Köszönöm!Azt szeretném kérdezni ,hogy amikor azt mondod ,hogy le tudod futtatni a profilert ,hogy megnézd ,hogy összeálltál vagy nem ,hogyan tudod ezt megtenni ?Például futás :nvprof --metrics gld_efficiency ? És minél magasabb, annál jobb? 29.09.2014
  • @George A vizuális profilozót használtam. A nvprof hatékony eszköznek tűnik, amely az Ön számára is használható. Szeretném hangsúlyozni, hogy a fontos mutatók az eszköz számítási képességétől és a CUDA-verziótól függenek, és a nvprof-nak lehetővé kell tennie ezek bármelyikének megfigyelését. Először állítsa működésbe a kernelt, majd optimalizálja a rendelkezésre álló profilozók bármelyikével. 01.10.2014
  • @jmilloy: Rendben, köszönöm, csak azt akartam tudni, hogy ez a gld_efficiency parancs-e ehhez. 01.10.2014
  • @jmilloy Viszonylag hülye kérdés, de mi a probléma, ha a memóriaelérés nem egyesült (1. lehetőség a példádban.)? A szálak továbbra is hozzáférnek az adatokhoz, és nincsenek versenyfeltételek. 25.01.2018
  • @filtfilt szekvenciális (egyidejű) olvasások, tehát hatástalanság. 27.01.2018
  • btw Szerintem 2018-ban (mint a compute 2 után) a half warp-ot warp-ra kellene cserélni ebben a válaszban. 04.10.2018
  • Mi a teendő, ha minden szál egyszerre éri el ugyanazt a (globális) memóriahelyet? Ez is egy összevont hozzáférés, vagy lassabb? 05.10.2019

  • 2

    A memóriaegyesítés olyan technika, amely lehetővé teszi a globális memória sávszélességének optimális kihasználását. Ez azt jelenti, hogy ha párhuzamos szálak futtatják ugyanazt az utasítást, akkor a globális memória egymást követő helyeihez férnek hozzá, akkor a legkedvezőbb hozzáférési mintát érik el.

    ide írja be a kép leírását

    A fenti ábra példája segít elmagyarázni az egyesített elrendezést:

    Az (a) ábrán n m hosszúságú vektor lineárisan van tárolva. A j vektor i elemét v j i jelöli. A GPU-kernel minden szála egy m hosszúságú vektorhoz van hozzárendelve. A CUDA szálai egy blokktömbbe vannak csoportosítva, és a GPU-ban minden szál egyedi azonosítóval rendelkezik, amely indx=bd*bx+tx-ként definiálható, ahol a bd a blokk dimenzióját jelöli, a bx a blokk indexét és a tx a szál indexét jelenti minden blokkban.

    A függőleges nyilak azt az esetet mutatják, amikor párhuzamos szálak férnek hozzá az egyes vektorok első összetevőihez, azaz a memória 0, m, 2m... címeihez. Amint az (a) ábrán látható, ebben az esetben a memória hozzáférés nem egymást követő. A címek közötti hézag nullázásával (piros nyilak látható a fenti ábrán), a memória-hozzáférés egyesül.

    A probléma azonban itt kissé bonyolulttá válik, mivel a GPU blokkonkénti tartózkodási szálak megengedett mérete bd-ra van korlátozva. Ezért az összevont adatelrendezés történhet úgy, hogy az első bd vektorok első elemeit egymás utáni sorrendben tároljuk, majd a második bd vektorok első elemeit és így tovább. A többi vektorelemet hasonló módon tároljuk, amint az a (b) ábrán látható. Ha az n (vektorok száma) nem bd tényező, akkor az utolsó blokk fennmaradó adatait fel kell tölteni valamilyen triviális értékkel, pl. 0.

    Az (a) ábrán látható lineáris adattárolóban az indx vektor i összetevője (0 ≤ im) em> (0 ≤ indxn) címét a m × indx +i; a (b) ábrán szereplő egyesített tárolási mintában ugyanaz a komponens van megcímezve

    (m × bd) ixC + bd × ixB + ixA,

    ahol ixC = floor[(m.indx + j )/(m.bd)]= bx, ixB = j és ixA = mod(indx,bd) = tx.

    Összefoglalva, a több, m méretű vektor tárolására vonatkozó példában a lineáris indexelés az egyesített indexelésre van leképezve a következőképpen:

    m.indx +i −→ m.bd.bx +i .bd +tx

    Ez az adatátrendezés a GPU globális memóriájának jelentősen nagyobb memóriasávszélességéhez vezethet.


    forrás: "Számítások GPU-alapú gyorsítása nemlineáris végeselem-deformációs elemzésben." Az orvosbiológiai mérnöki numerikus módszerek nemzetközi folyóirata (2013).

    14.02.2014

    3

    Ha egy blokkban lévő szálak egymást követő globális memóriahelyekhez férnek hozzá, akkor a hardver az összes hozzáférést egyetlen kérelemben egyesíti (vagy egyesíti). A mátrix példában a sorban lévő mátrixelemek lineárisan vannak elrendezve, majd a következő sor következik, és így tovább. Például 2x2 mátrix és 2 szál esetén egy blokkban a memóriahelyek a következőképpen vannak elrendezve:

    (0,0) (0,1) (1,0) (1,1)

    A sorelérésben a szál1 eléri a (0,0) és (1,0) értékeket, amelyeket nem lehet egyesíteni. Az oszlopelérésben a szál1 eléri a (0,0) és a (0,1) értékeket, amelyek egyesíthetők, mivel szomszédosak.

    18.02.2011
  • szép és tömör, de ne feledd, hogy a koalesced nem két soros hozzáférésről szól 1 szálon keresztül, hanem egyidejűleg, párhuzamosan 1 és 2 szálon keresztül. A sorelérési példában, ha a szál1 eléri (0,0) és (1,0), akkor feltételezem, hogy a szál2 eléri a (0,1) és (1,1) értékeket. Így az első párhuzamos hozzáférés 1:(0,0) és 2:(0,1) --› összeáll! 18.02.2011

  • 4

    Az összevonás feltételeit a CUDA 3.2 programozási útmutatója szépen dokumentálja., G.3.2. A rövid változat a következő: a warp szálainak sorban kell elérniük a memóriát, és az elérendő szavaknak >=32 bitesnek kell lenniük. Ezenkívül a vetemítés által elért alapcímnek 64, 128 vagy 256 bájtosnak kell lennie a 32, 64 és 128 bites hozzáférésekhez igazítva.

    A Tesla2 és a Fermi hardver megfelelő munkát végez a 8 és 16 bites hozzáférések összekapcsolásában, de legjobb elkerülni ezeket, ha csúcs sávszélességre vágynak.

    Ne feledje, hogy a Tesla2 és a Fermi hardver fejlesztései ellenére az összevonás SEMMILYEN SZEMÉLYESEN elavult. Még a Tesla2 vagy a Fermi osztályú hardvereken is a globális memóriatranzakciók összevonásának elmulasztása kétszeres teljesítménycsökkenést eredményezhet. (A Fermi osztályú hardvereken ez csak akkor igaz, ha az ECC engedélyezve van. A szomszédos, de össze nem kapcsolt memóriatranzakciók körülbelül 20%-os sikert érnek el a Fermi esetében.)

    23.04.2011
    Új anyagok

    A rádiógomb ellenőrzött eseményének használata a jQueryben
    Ebben a cikkben látni fogjuk, hogyan kell dolgozni a jquery választógombbal ellenőrzött eseményeivel. A választógombok HTML gombok, amelyek segítenek kiválasztani egyetlen értéket egy csoportból...

    Körkörös függőségek megoldása terraformban adatforrásokkal – lépésről lépésre
    Mi az a körkörös függőségek Dolgozzunk egy egyszerű eseten, amikor az SQS-sor és az S3-vödör közötti körkörös függőség problémája van egy egymástól függő címkeérték miatt. provider..

    Miért érdemes elkezdeni a kódolást 2023-ban?
    01100011 01101111 01100100 01100101 — beep boop beep boop Világunk folyamatosan fejlődik a technológia körül, és naponta fejlesztenek új technológiákat a valós problémák megoldására. Amint..

    🎙 Random Noise #2  – Örökbefogadás és hit
    az analitika íratlan világának gondozása Szeretné, hogy ezek a frissítések a postaládájába kerüljenek? Iratkozzon fel itt . "Ha önvezető autókat gyártanak, akkor mi miért ne..

    A legrosszabb politika és prediktív modellek májátültetésre jelöltek számára az Egyesült Államokban
    A máj (vagy óangolul lifer) az emberi test legnehezebb belső szervére utal, amely csendesen működik a nap 24 órájában. Mit csinál a máj? 500 feladatot hajt végre a szervezet egészségének..

    5 webhely, amely 2022-ben fejleszti front-end fejlesztői készségeit
    Frontendmentor.io A tényleges projektek létrehozásával a Frontendmentor.io segítséget nyújt a front-end kódolási képességeinek fejlesztésében. A kódolást azután kezdheti meg, hogy..

    Mikor kell használni a Type-t az interfészhez képest a TypeScriptben?
    A TypeScript a JavaScript gépelt szuperkészlete, amely statikus gépelést ad a nyelvhez. Ez megkönnyíti a robusztus és karbantartható kód írását azáltal, hogy a hibákat a fordítási időben..