GPU-optimering - sanningar. Beräkning på GPU Exempel på teknologiapplikation

26.02.2022

På tal om parallell beräkning på GPU:er måste vi komma ihåg vilken tid vi lever i, idag är en tid då allt i världen accelereras så mycket att du och jag tappar koll på tiden, utan att lägga märke till hur den rusar förbi. Allt vi gör är förknippat med hög noggrannhet och snabb informationsbehandling, under sådana förhållanden behöver vi verkligen verktyg för att bearbeta all information som vi har och omvandla den till data, dessutom måste vi komma ihåg att dessa uppgifter när vi pratar om sådana uppgifter är nödvändiga inte bara för stora organisationer eller megaföretag, utan också för vanliga användare som löser sina livsproblem relaterade till högteknologi hemma på persondatorer! Framväxten av NVIDIA CUDA var inte förvånande, utan snarare motiverad, eftersom det snart kommer att bli nödvändigt att bearbeta betydligt mer tidskrävande uppgifter på PC:n än tidigare. Arbete som tidigare tagit mycket tid kommer nu att ta några minuter, och följaktligen kommer detta att påverka helhetsbilden av hela världen!

Vad är GPU-datorer?

GPU-beräkning är användningen av GPU:n för att beräkna tekniska, vetenskapliga och vardagliga uppgifter. GPU-beräkning involverar användningen av CPU och GPU med heterogen sampling mellan dem, nämligen: den sekventiella delen av programmen tas över av CPU:n, medan tidskrävande beräkningsuppgifter lämnas till GPU:n. Tack vare detta sker parallellisering av uppgifter, vilket leder till snabbare informationsbehandling och minskar arbetsutförandetiden blir systemet mer produktivt och kan samtidigt bearbeta ett större antal uppgifter än tidigare. Men för att nå sådan framgång räcker inte enbart hårdvarustöd i detta fall, mjukvarustöd är också nödvändigt så att applikationen kan överföra de mest tidskrävande beräkningarna till GPU:n.

Vad är CUDA

CUDA är en teknik för programmering av algoritmer i det förenklade C-språket som körs på grafikprocessorer av GeForce-acceleratorer av åttonde generationen och äldre, samt motsvarande Quadro- och Tesla-kort från NVIDIA. CUDA låter dig inkludera specialfunktioner i texten i ett C-program. Dessa funktioner är skrivna i det förenklade programmeringsspråket C och körs på GPU:n. Den första versionen av CUDA SDK introducerades den 15 februari 2007. För att framgångsrikt översätta kod till detta språk inkluderar CUDA SDK NVIDIAs egen nvcc kommandorad C-kompilator. nvcc-kompilatorn är baserad på den öppna Open64-kompilatorn och är utformad för att översätta värdkod (huvud-, kontrollkod) och enhetskod (hårdvarukod) (filer med .cu-tillägget) till objektfiler som är lämpliga för sammansättning av det slutliga programmet eller biblioteket i alla programmeringsmiljöer, till exempel Microsoft Visual Studio.

Tekniska möjligheter

  1. Ett standard C-språk för parallell applikationsutveckling på GPU:er.
  2. Färdiga numeriska analysbibliotek för snabb Fourier-transform och grundläggande linjär algebra-mjukvarupaket.
  3. Speciell CUDA-drivrutin för beräkning med snabb dataöverföring mellan GPU och CPU.
  4. Möjlighet att koppla CUDA-drivrutinen med OpenGL- och DirectX-grafikdrivrutiner.
  5. Stöd för Linux 32/64-bitars, Windows XP 32/64-bitars och MacOS operativsystem.

Teknikens fördelar

  1. CUDA Application Programming Interface (CUDA API) är baserat på standardprogrammeringsspråket C med vissa begränsningar. Detta förenklar och smidigar processen att lära sig CUDA-arkitekturen.
  2. Det delade minnet på 16 KB mellan trådar kan användas för en användarorganiserad cache med en bredare bandbredd än när man hämtar från vanliga texturer.
  3. Effektivare transaktioner mellan CPU-minne och videominne.
  4. Fullständigt hårdvarustöd för heltals- och bitvisa operationer.

Exempel på tekniktillämpning

cRark

Den mest tidskrävande delen av detta program är tinkturen. Programmet har ett konsolgränssnitt, men tack vare instruktionerna som följer med själva programmet kan du använda det. Följande är korta instruktioner för att ställa in programmet. Vi kommer att testa programmet för funktionalitet och jämföra det med ett annat liknande program som inte använder NVIDIA CUDA, i det här fallet det välkända programmet "Advanced Archive Password Recovery".

Från det nedladdade cRark-arkivet behöver vi bara tre filer: crark.exe, crark-hp.exe och password.def. Crerk.exe är ett konsolobduktionsverktyg RAR-lösenord 3.0 utan krypterade filer inne i arkivet (dvs när vi öppnar arkivet ser vi namnen, men kan inte packa upp arkivet utan lösenord).

Crerk-hp.exe är ett konsolverktyg för att öppna RAR 3.0-lösenord med kryptering av hela arkivet (dvs. när vi öppnar arkivet ser vi varken namnet eller själva arkiven och kan inte packa upp arkivet utan lösenord).

Password.def är en omdöpt textfil med väldigt lite innehåll (till exempel: 1:a raden: ## 2:a raden: ?* , i detta fall kommer lösenordet att knäckas med alla tecken). Password.def är chef för cRark-programmet. Filen innehåller reglerna för att knäcka lösenordet (eller området med tecken som crark.exe kommer att använda i sitt arbete). Mer information om möjligheterna att välja dessa tecken finns i textfilen som erhålls när du öppnar den som laddats ner från webbplatsen för författaren till cRark-programmet: russian.def.

Förberedelse

Jag ska genast säga att programmet bara fungerar om ditt grafikkort är baserat på en GPU som stöder CUDA 1.1 accelerationsnivån. Så en serie grafikkort baserade på G80-chippet, såsom GeForce 8800 GTX, behövs inte längre, eftersom de har hårdvarustöd för CUDA 1.0-acceleration. Programmet väljer endast lösenord för RAR-arkiv av version 3.0+ med CUDA. Allt måste installeras programvara relaterat till CUDA, nämligen:

Vi skapar vilken mapp som helst på valfri plats (till exempel på C:-enheten) och kallar den valfritt namn, till exempel "3.2". Vi placerar filerna där: crark.exe, crark-hp.exe och password.def och ett lösenordsskyddat/krypterat RAR-arkiv.

Därefter bör du starta Windows kommandoradskonsol och gå till den skapade mappen. I Windows Vista och 7 ska du anropa "Start"-menyn och ange "cmd.exe" i sökfältet i Windows XP, från "Start"-menyn ska du först anropa "Kör"-dialogrutan och ange "cmd .exe” i den. När du har öppnat konsolen anger du ett kommando som: cd C:\folder\, cd C:\3.2 i det här fallet.

Rekrytering kl textredigerare två rader (du kan också spara texten som en .bat-fil i mappen med cRark) för att gissa lösenordet till ett lösenordsskyddat RAR-arkiv med okrypterade filer:

eko av;
cmd /K crark (arkivnamn).rar

för att gissa lösenordet för ett lösenordsskyddat och krypterat RAR-arkiv:

eko av;
cmd /K crark-hp (arkivnamn).rar

Kopiera 2 rader av textfilen till konsolen och tryck på Enter (eller kör .bat-filen).

resultat

Dekrypteringsprocessen visas i figuren:

Hastigheten att gissa på cRark med CUDA var 1625 lösenord/sekund. På en minut och trettiosex sekunder valdes ett lösenord med 3 tecken: "q)$." Som jämförelse: sökhastigheten i Advanced Archive Password Recovery på min dual-core Athlon-processor 3000+ motsvarar maximalt 50 lösenord/sekund och sökningen skulle behöva pågå i 5 timmar. Det vill säga att bruteforce-val av ett RAR-arkiv i cRark med ett GeForce 9800 GTX+ grafikkort är 30 gånger snabbare än på en CPU.

För de som har Intel-processor, ett bra moderkort med hög systembussfrekvens (FSB 1600 MHz), blir CPU-hastigheten och sökhastigheten högre. Och om du har en fyrkärnig processor och ett par grafikkort på GeForce 280 GTX-nivån, kommer hastigheten på brute-forcing-lösenord att öka avsevärt. För att sammanfatta exemplet måste det sägas att detta problem löstes med CUDA-teknik på bara 2 minuter istället för 5 timmar, vilket indikerar den höga potentialen hos denna teknik!

Slutsatser

Efter att ha undersökt tekniken för parallellberäkning CUDA idag, såg vi tydligt all kraft och enorm potential för utvecklingen av denna teknik med hjälp av exemplet med ett program för lösenordsåterställning för RAR-arkiv. Det måste sägas om utsikterna för denna teknik, denna teknik kommer säkerligen att hitta en plats i livet för varje person som bestämmer sig för att använda den, vare sig det är vetenskapliga uppgifter eller uppgifter relaterade till videobearbetning, eller till och med ekonomiska uppgifter som kräver snabba, exakta beräkningar kommer allt detta att leda till en oundviklig ökning av arbetsproduktiviteten som inte kan ignoreras. Idag börjar frasen "hemsuperdator" redan komma in i lexikonet; Det är helt uppenbart att för att göra ett sådant föremål till verklighet har varje hem redan ett verktyg som heter CUDA. Sedan släppet av kort baserade på G80-chippet (2006) har ett stort antal NVIDIA-baserade acceleratorer släppts som stödjer CUDA-teknik, vilket kan förverkliga drömmar om superdatorer i varje hem. Genom att marknadsföra CUDA-teknik höjer NVIDIA sin auktoritet i kundernas ögon i form av att tillhandahålla ytterligare möjligheter till deras utrustning, som många redan har köpt. Vi kan bara tro att CUDA snart kommer att utvecklas mycket snabbt och tillåta användare att dra full nytta av alla möjligheter med parallell beräkning på GPU:er.

Funktioner i AMD/ATI Radeon-arkitekturen

Detta liknar födelsen av nya biologiska arter, när, under utvecklingen av livsmiljöer, levande varelser utvecklas för att förbättra sin anpassningsförmåga till miljön. På samma sätt utvecklade GPU:n, som började med att accelerera rastreringen och textureringen av trianglar, ytterligare möjligheter för att köra skuggningsprogram för att färga samma trianglar. Och dessa förmågor är också efterfrågade inom icke-grafisk datoranvändning, där de i vissa fall ger betydande prestandavinster jämfört med traditionella lösningar.

Låt oss dra ytterligare analogier - efter en lång evolution på land trängde däggdjur in i havet, där de fördrev vanliga marina invånare. I konkurrensen använde däggdjur både nya avancerade förmågor som dök upp på jordens yta och de som särskilt förvärvats för anpassning till livet i vatten. På samma sätt utrustas GPU:er, baserat på fördelarna med arkitekturen för 3D-grafik, alltmer med speciella funktionalitet, användbar för att utföra uppgifter som är långt ifrån grafik.

Så, vad gör det möjligt för GPU:er att göra anspråk på sin egen sektor i det allmänna programvaruutrymmet? GPU-mikroarkitekturen är byggd helt annorlunda än den för konventionella CPU: er, och den innehåller i sig vissa fördelar. Grafikuppgifter kräver oberoende parallell bearbetning, och GPU:n är naturligt flertrådad. Men denna parallellitet ger honom bara glädje. Mikroarkitekturen är designad för att utnyttja befintliga Ett stort antal trådar som kräver exekvering.

GPU:n består av flera dussin (30 för Nvidia GT200, 20 för Evergreen, 16 för Fermi) processorkärnor, som kallas Streaming Multiprocessor i Nvidia-terminologi, och SIMD Engine i ATI-terminologi. I den här artikeln kommer vi att kalla dem miniprocessorer, eftersom de kör flera hundra programtrådar och kan göra nästan allt som en vanlig CPU kan göra, men ändå inte allt.

Marknadsföringsnamn är förvirrande - för större betydelse indikerar de antalet funktionella moduler som kan subtrahera och multiplicera: till exempel 320 vektor "kärnor". Dessa kärnor är mer som spannmål. Det är bättre att tänka på GPU:n som en slags flerkärnig processor med ett stort antal kärnor som kör många trådar samtidigt.

Varje miniprocessor har lokalt minne, 16 KB för GT200, 32 KB för Evergreen och 64 KB för Fermi (i huvudsak en programmerbar L1-cache). Den har en åtkomsttid som liknar den första nivåns cache hos en konventionell CPU och utför liknande funktioner för snabbast leverans av data till funktionsmoduler. I Fermi-arkitekturen kan en del av det lokala minnet konfigureras som en vanlig cache. I en GPU används lokalt minne för snabbt datautbyte mellan exekverande trådar. Ett av de vanliga schemana för ett GPU-program är följande: först laddas data från GPU:s globala minne in i det lokala minnet. Detta är bara vanligt videominne, placerat (som systemminne) separat från "dess" processor - när det gäller video löds det av flera chips på grafikkortets PCB. Därefter arbetar flera hundra trådar med dessa data i lokalt minne och skriver resultatet till det globala minnet, varefter det överförs till CPU:n. Det är programmerarens ansvar att skriva instruktioner för laddning och urladdning av data från lokalt minne. I huvudsak är det att partitionera [en specifik uppgift] data för parallell bearbetning. GPU:n stöder också atomära skriv/läs-instruktioner i minnet, men de är ineffektiva och behövs vanligtvis i slutskedet för att "limma ihop" beräkningsresultaten för alla miniprocessorer.

Lokalt minne är gemensamt för alla trådar som körs i miniprocessorn, därför kallas det till exempel i Nvidia-terminologi till och med delat, och termen lokalt minne betecknar raka motsatsen, nämligen: ett visst personligt område i en separat tråd i globalt minne, synligt och tillgängligt endast för det. Men förutom lokalt minne har miniprocessorn ytterligare ett minnesområde, som i alla arkitekturer är ungefär fyra gånger större i volym. Den delas lika mellan alla exekverande trådar. Dessa är register för lagring av variabler och mellanberäkningsresultat. Varje tråd har flera dussin register. Det exakta antalet beror på hur många trådar miniprocessorn kör. Detta nummer är mycket viktigt, eftersom latensen för globalt minne är mycket hög, hundratals cykler, och i frånvaro av cacher finns det ingenstans att lagra mellanliggande beräkningsresultat.

Och ytterligare en viktig egenskap hos GPU:n: "mjuk" vektorisering. Varje miniprocessor har ett stort antal beräkningsmoduler (8 för GT200, 16 för Radeon och 32 för Fermi), men alla kan bara köra samma instruktion, med samma programadress. I det här fallet kan operanderna vara olika, olika trådar har sina egna. Till exempel instruktioner lägga till innehållet i två register: det exekveras samtidigt av alla datorenheter, men registren tas olika. Det antas att alla trådar i GPU-programmet, som utför parallell databehandling, i allmänhet rör sig i en parallell kurs genom programkoden. Således laddas alla beräkningsmoduler jämnt. Och om trådarna divergerar i sin kodexekveringsväg på grund av förgreningar i programmet, så inträffar så kallad serialisering. Då används inte alla beräkningsmoduler, eftersom trådarna skickar olika instruktioner för exekvering, och ett block av beräkningsmoduler kan exekvera, som vi redan har sagt, endast en instruktion med en adress. Och, naturligtvis, sjunker produktiviteten i förhållande till maximum.

Fördelen är att vektorisering är helt automatisk, det är inte programmering med hjälp av SSE, MMX och så vidare. Och GPU själv hanterar avvikelserna. Teoretiskt kan du i allmänhet skriva program för GPU:n utan att tänka på vektorkaraktären hos exekveringsmodulerna, men hastigheten för ett sådant program kommer inte att vara särskilt hög. Nackdelen är den stora bredden på vektorn. Det är större än det nominella antalet funktionsmoduler och är 32 för Nvidia GPU:er och 64 för Radeon. Trådarna bearbetas i block av lämplig storlek. Nvidia kallar det här trådblocket för termen warp, AMD kallar det för vågfront, vilket är samma sak. Således, på 16 datorenheter, bearbetas en "vågfront" med en längd på 64 trådar i fyra klockcykler (förutsatt att den vanliga instruktionslängden antas). Författaren föredrar termen varp i det här fallet, på grund av kopplingen till den nautiska termen varp, vilket betyder ett rep som knyts ihop av tvinnade rep. Så trådarna "vrider sig" och bildar en solid bunt. Men "vågfront" kan också förknippas med havet: instruktioner kommer till ställdonen på samma sätt som vågorna rullar in på stranden en efter en.

Om alla trådar är lika avancerade i programexekveringen (placerade på samma plats) och därmed kör samma instruktion, så är allt bra, men om inte, uppstår en avmattning. I det här fallet finns trådar från en varp- eller vågfront på olika ställen i programmet de är uppdelade i grupper av trådar som har samma instruktionsnummervärde (med andra ord instruktionspekare). Och bara trådarna i en grupp körs fortfarande samtidigt - alla kör samma instruktion, men med olika operander. Som ett resultat går warp lika många gånger långsammare som antalet grupper den är indelad i, och antalet trådar i gruppen spelar ingen roll. Även om gruppen bara består av en tråd, kommer det fortfarande att ta lika lång tid att utföra som en full warp. I hårdvara implementeras detta genom att maskera vissa trådar, det vill säga instruktioner exekveras formellt, men resultaten av deras exekvering registreras inte någonstans och används inte i framtiden.

Även om varje miniprocessor (Streaming MultiProcessor eller SIMD Engine) vid varje given tidpunkt exekverar instruktioner som bara tillhör en warp (ett gäng trådar), har den flera dussin aktiva warps i exekveringspoolen. Efter att ha utfört instruktionerna för en varp, exekverar miniprocessorn inte nästa instruktion för trådarna i denna varp, utan instruktionerna för någon annan varp. Den varpningen kan vara på en helt annan plats i programmet, detta kommer inte att påverka hastigheten, eftersom endast inuti varpningen måste instruktionerna för alla trådar vara desamma för utförande i full fart.

I det här fallet har var och en av de 20 SIMD-motorerna fyra aktiva vågfronter, var och en med 64 trådar. Varje tråd indikeras med en kort linje. Totalt: 64×4×20=5120 trådar

Med tanke på att varje varp- eller vågfront består av 32-64 trådar har miniprocessorn alltså flera hundra aktiva trådar som exekveras nästan samtidigt. Nedan kommer vi att se vilka arkitektoniska fördelar ett så stort antal parallella trådar lovar, men först ska vi överväga vilka begränsningar miniprocessorerna som utgör GPU:n har.

Huvudsaken är att GPU:n inte har en stack där funktionsparametrar och lokala variabler kan lagras. På grund av det stora antalet trådar finns det helt enkelt inget utrymme på chippet för stacken. Eftersom GPU:n kör ungefär 10 000 trådar samtidigt, med en stackstorlek på en tråd på 100 KB, blir den totala volymen 1 GB, vilket är lika med standardmängden för allt videominne. Dessutom finns det inget sätt att placera en stack av någon betydande storlek i själva GPU-kärnan. Till exempel, om du lägger 1000 byte av stack på en tråd, skulle bara en miniprocessor kräva 1 MB minne, vilket är nästan fem gånger den kombinerade mängden lokalt minne för miniprocessorn och det minne som allokerats för lagring av register.

Därför finns det ingen rekursion i ett GPU-program, och det finns inte mycket att göra med funktionsanrop. Alla funktioner infogas direkt i koden vid kompilering av programmet. Detta begränsar omfattningen av GPU-applikationer till uppgifter av beräkningstyp. Det är ibland möjligt att använda begränsad stackemulering med globalt minne för rekursionsalgoritmer med kända små iterationsdjup, men detta är inte en typisk GPU-applikation. För att göra detta är det nödvändigt att speciellt utveckla en algoritm och utforska möjligheten för dess implementering utan att garantera framgångsrik acceleration jämfört med CPU.

Fermi introducerade möjligheten att använda virtuella funktioner för första gången, men återigen begränsas deras användning av avsaknaden av en stor, snabb cache för varje tråd. 1536 trådar står för 48 KB eller 16 KB av L1, det vill säga virtuella funktioner i ett program kan användas relativt sällan, annars kommer stacken också att använda långsamt globalt minne, vilket kommer att sakta ner exekvering och troligen inte kommer att ge fördelar jämfört med CPU-versionen.

Således representeras GPU:n som en datorsamprocessor i vilken data laddas, den bearbetas av någon algoritm och resultatet produceras.

Arkitekturfördelar

Men den beräknar GPU mycket snabbt. Och dess höga multithreading hjälper den med detta. Ett stort antal aktiva trådar gör det möjligt att delvis dölja den höga latensen för det separat placerade globala videominnet, vilket är cirka 500 klockcykler. Det är utjämnat särskilt bra för kod med hög densitet av aritmetiska operationer. Den transistordyra L1-L2-L3 cachehierarkin krävs således inte. Istället kan flera beräkningsmoduler placeras på chippet, vilket ger enastående aritmetisk prestanda. Medan instruktionerna för en tråd eller varp exekveras, väntar de återstående hundratals trådarna tyst på sina data.

Fermi introducerade en L2-cache på cirka 1 MB, men den kan inte jämföras med cacher moderna processorer, den är mer avsedd för kommunikation mellan kärnor och olika mjukvarutrick. Om dess storlek är uppdelad på alla tiotusentals trådar kommer var och en att ha en mycket försumbar volym.

Men förutom global minnesfördröjning finns det många fler latenser i en datorenhet som måste döljas. Detta är latensen för dataöverföring på chip från datorenheter till första nivåns cache, det vill säga det lokala minnet hos GPU:n, och till registren, såväl som instruktionscachen. Registerfilen, såväl som det lokala minnet, är placerade separat från funktionsmodulerna, och åtkomsthastigheten till dem är ungefär ett och ett halvt dussin cykler. Och återigen, ett stort antal trådar, aktiva varpar, kan effektivt dölja denna latens. Dessutom är den totala åtkomstbandbredden (bandbredden) till det lokala minnet för hela grafikprocessorn, med hänsyn till antalet miniprocessorer som den består av, betydligt större än åtkomstbandbredden till den första nivåns cache hos moderna processorer. GPU:n kan bearbeta betydligt mer data per tidsenhet.

Vi kan omedelbart säga att om GPU:n inte är försedd med ett stort antal parallella trådar, kommer den att ha nästan noll prestanda, eftersom den kommer att fungera i samma takt som om den är fulladdad och kommer att göra mycket mindre arbete. Låt det till exempel bara finnas en tråd istället för 10 000: prestandan kommer att sjunka med ungefär tusen gånger, för inte bara kommer inte alla block att laddas, utan alla latenser kommer också att påverkas.

Problemet med att dölja latenser är också akut för moderna högfrekventa processorer som används för att eliminera det - djup pipelining, utförande av instruktioner. Detta kräver komplexa instruktionsschemaläggare, olika buffertar etc. som tar upp plats på chippet. Allt detta krävs för bästa entrådiga prestanda.

Men allt detta behövs inte för GPU:n, det är arkitektoniskt snabbare för datoruppgifter med ett stort antal trådar. Men det förvandlar multithreading till prestanda, som de vises sten förvandlar bly till guld.

GPU:n designades ursprungligen för optimal exekvering av skuggningsprogram för triangelpixlar, som uppenbarligen är oberoende och kan köras parallellt. Och från detta tillstånd har det utvecklats genom att lägga till olika funktioner (lokalt minne och adresserbar åtkomst till videominne, samt komplicera instruktionsuppsättningen) till en mycket kraftfull datorenhet, som fortfarande kan användas effektivt endast för algoritmer som tillåter mycket parallell implementering använda en begränsad mängd lokalt minne.

Exempel

Ett av de mest klassiska problemen för GPU är problemet med att beräkna samverkan mellan N kroppar som skapar ett gravitationsfält. Men om vi till exempel behöver beräkna utvecklingen av Earth-Moon-Sun-systemet, så är GPU:n en dålig hjälp för oss: det finns få objekt. För varje objekt är det nödvändigt att beräkna interaktioner med alla andra objekt, och det finns bara två av dem. När det gäller solsystemets rörelse med alla planeter och deras månar (ungefär ett par hundra objekt) är GPU:n fortfarande inte särskilt effektiv. Men på grund av den höga omkostnaden för trådhantering kommer en flerkärnig processor inte heller att kunna visa all sin kraft och kommer att fungera i enkeltrådigt läge. Men om du också behöver beräkna banorna för kometer och asteroidbältsobjekt, är detta redan en uppgift för GPU:n, eftersom det finns tillräckligt med objekt för att skapa det nödvändiga antalet parallella beräkningstrådar.

GPU:n kommer också att fungera bra om du behöver beräkna kollisionen av klothopar med hundratusentals stjärnor.

En annan möjlighet att använda GPU-kraft i ett N-kroppsproblem uppstår när du behöver beräkna många individuella problem, om än med ett litet antal kroppar. Till exempel, om du behöver beräkna alternativ för utvecklingen av ett system för olika alternativ för initiala hastigheter. Då kan du effektivt använda GPU:n utan problem.

AMD Radeon mikroarkitektur detaljer

Vi tittade på de grundläggande principerna för GPU-organisation de är gemensamma för videoacceleratorer från alla tillverkare, eftersom de från början hade en måluppgift - shader-program. Tillverkarna har dock hittat en möjlighet att skilja på detaljerna i den mikroarkitektoniska implementeringen. Även om CPU:er från olika leverantörer ibland är väldigt olika, även om de är kompatibla, som Pentium 4 och Athlon eller Core. Nvidia-arkitekturen är redan ganska allmänt känd, nu ska vi titta på Radeon och lyfta fram de viktigaste skillnaderna i dessa leverantörers tillvägagångssätt.

AMD-grafikkort fick fullt stöd för allmänt bruk från och med Evergreen-familjen, som också implementerade DirectX 11-specifikationer för första gången, har ett antal betydande begränsningar, som kommer att diskuteras nedan.

Skillnaderna i storleken på lokalt minne (32 KB för Radeon mot 16 KB för GT200 och 64 KB för Fermi) är i allmänhet inte signifikanta. Samt vågfrontsstorleken på 64 trådar för AMD kontra 32 trådar i warp för Nvidia. Nästan alla GPU-program kan enkelt konfigureras om och justeras till dessa parametrar. Prestanda kan ändras med tiotals procent, men i fallet med en GPU är detta inte så viktigt, eftersom ett GPU-program vanligtvis körs tio gånger långsammare än sin CPU-motsvarighet, eller tio gånger snabbare, eller inte fungerar alls.

Viktigare är AMD:s användning av VLIW-teknik (Very Long Instruction Word). Nvidia använder skalär enkla instruktioner, som arbetar med skalära register. Dess acceleratorer implementerar enkla klassiska RISC. AMD grafikkort har samma antal register som GT200, men registren är 128-bitars vektorer. Varje VLIW-instruktion fungerar på flera fyrkomponents 32-bitarsregister, vilket liknar SSE, men VLIW har mycket fler möjligheter. Detta är inte SIMD (Single Instruction Multiple Data) som SSE - här kan instruktionerna för varje par av operander vara olika och till och med beroende! Låt till exempel komponenterna i register A kallas a1, a2, a3, a4; register B är liknande. Kan beräknas med en enda instruktion som körs i en klockcykel, till exempel talet a1×b1+a2×b2+a3×b3+a4×b4 eller en tvådimensionell vektor (a1×b1+a2×b2, a3 ×b3+a4×b4).

Detta möjliggjordes på grund av den lägre frekvensen hos GPU:n än CPU:n och den kraftiga minskningen av processteknologi de senaste åren. I det här fallet krävs ingen schemaläggare; nästan allt exekveras i en klockcykel.

Tack vare vektorinstruktioner är Radeons toppprestanda med enkel precision mycket hög och når teraflops.

Ett vektorregister kan lagra ett dubbelt precisionsnummer istället för fyra enkla precisionsnummer. Och en VLIW-instruktion kan antingen lägga till två par dubbla tal, eller multiplicera två tal, eller multiplicera två tal och addera med ett tredje. Således är toppprestanda i dubbel ungefär fem gånger lägre än i float. För äldre Radeon-modeller motsvarar det prestandan hos Nvidia Tesla på den nya Fermi-arkitekturen och är mycket högre än prestandan för dubbla kort på GT200-arkitekturen. I konsument Geforce grafikkort baserade på Fermi maxhastighet dubbla beräkningar har reducerats med fyra gånger.


Schematiskt diagram över Radeon-drift. Endast en miniprocessor av 20 som körs parallellt presenteras

GPU-tillverkare, till skillnad från CPU-tillverkare (främst x86-kompatibla sådana), är inte bundna av kompatibilitetsproblem. Ett GPU-program kompileras först till någon mellankod, och när programmet körs kompilerar drivrutinen denna kod till modellspecifika maskininstruktioner. Som beskrivits ovan har GPU-tillverkare utnyttjat detta genom att komma med bekväm ISA (Instruction Set Architecture) för sina GPU:er och ändra dem från generation till generation. I alla fall tillförde detta en viss procent av prestanda på grund av frånvaron (som onödig) av en avkodare. Men AMD gick ännu längre genom att ta fram ett eget format för att ordna instruktioner i maskinkod. De är inte ordnade sekventiellt (enligt programlistan), utan i sektioner.

Först kommer avsnittet med villkorliga greninstruktioner, som har länkar till avsnitt av kontinuerliga aritmetiska instruktioner som motsvarar de olika grengrenarna. De kallas VLIW-buntar. Dessa avsnitt innehåller endast aritmetiska instruktioner med data från register eller lokalt minne. Denna organisation förenklar hanteringen av flödet av instruktioner och deras leverans till verkställande enheter. Detta är desto mer användbart med tanke på att VLIW-instruktionerna är relativt stora. Det finns också avsnitt för instruktioner för minnesåtkomst.

Villkorliga hoppinstruktionssektioner
Avsnitt 0Filial 0Länk till avsnitt 3 i kontinuerliga räkneanvisningar
Sektion 1Gren 1Länk till avsnitt nr 4
Sektion 2Gren 2Länk till avsnitt nr 5
Kontinuerliga aritmetiska instruktionsavsnitt
Avsnitt 3VLIW-instruktion 0VLIW-instruktion 1VLIW-instruktion 2VLIW-instruktion 3
Avsnitt 4VLIW-instruktion 4VLIW-instruktion 5
Avsnitt 5VLIW-instruktion 6VLIW-instruktion 7VLIW-instruktion 8VLIW-instruktion 9

GPU:er från både Nvidia och AMD har också inbyggda instruktioner för att snabbt beräkna grundläggande matematiska funktioner, kvadratrot, exponent, logaritmer, sinus och cosinus för enstaka precisionstal i några klockcykler. Det finns speciella beräkningsenheter för detta. De "härstammar" från behovet av att implementera snabb approximation av dessa funktioner i geometriskuggare.

Även om någon inte visste att GPU:er används för grafik och bara läser de tekniska egenskaperna, så kunde han med detta tecken gissa att dessa datorsamprocessorer härrörde från videoacceleratorer. På samma sätt, baserat på vissa egenskaper hos marina däggdjur, insåg forskare att deras förfäder var landvarelser.

Men en mer uppenbar funktion som avslöjar enhetens grafiska ursprung är 2D- och 3D-texturläsningsenheterna med stöd för bilinjär interpolation. De används ofta i GPU-program, eftersom de ger snabbare och förenklad läsning av skrivskyddade datamatriser. Ett av standardbeteendena för en GPU-applikation är att läsa arrayer av källdata, bearbeta dem i datorkärnorna och skriva resultatet till en annan array, som sedan överförs tillbaka till CPU:n. Detta schema är standard och vanligt eftersom det är bekvämt för GPU-arkitekturen. Uppgifter som kräver intensiv läsning och skrivning i en stor region av det globala minnet, och därmed innehåller databeroenden, är svåra att parallellisera och implementera effektivt på GPU:n. Dessutom kommer deras prestanda till stor del att bero på latensen för globalt minne, vilket är mycket högt. Men om uppgiften beskrivs av mönstret "läsa data - bearbeta - skriva resultatet", så kan du nästan säkert få ett stort uppsving från att köra det på GPU:n.

För texturdata i GPU:n finns det en separat hierarki av små cacher på första och andra nivån. Detta är vad som ger acceleration från att använda texturer. Denna hierarki dök ursprungligen upp i GPU:er för att dra fördel av lokaliteten för åtkomst till texturer: uppenbarligen, efter bearbetning av en pixel, kommer en angränsande pixel (med hög sannolikhet) att kräva närliggande texturdata. Men många algoritmer för konventionella beräkningar har en liknande karaktär av dataåtkomst. Så texturcacher från grafik kommer att vara mycket användbara.

Även om storleken på L1-L2-cacharna i Nvidia- och AMD-kort är ungefär lika, vilket uppenbarligen orsakas av kraven på optimalitet vad gäller spelgrafik, varierar åtkomstlatensen till dessa cachar avsevärt. Nvidia har högre åtkomstlatens, och texturcacher i GeForce hjälper främst till att minska belastningen på minnesbussen, snarare än att direkt påskynda dataåtkomst. Detta märks inte i grafikprogram, men är viktigt för generella program. I Radeon är latensen för texturcachen lägre, men latensen för det lokala minnet hos miniprocessorer är högre. Vi kan ge följande exempel: för optimal matrismultiplikation på Nvidia-kort är det bättre att använda lokalt minne, ladda matrisen där block för block, och för AMD är bättre lita på en texturcache med låg latens, läser matriselement efter behov. Men detta är redan en ganska subtil optimering, och för en algoritm som redan har överförts i grunden till GPU:n.

Denna skillnad visar sig också när du använder 3D-texturer. En av de första GPU-beräkningarna, som visade en allvarlig fördel för AMD, använde 3D-texturer, eftersom den fungerade med en tredimensionell datamatris. Och latensen för åtkomst till texturer i Radeon är betydligt snabbare, och 3D-fallet är dessutom mer optimerat för hårdvara.

För att få maximal prestanda från hårdvara från olika företag krävs viss justering av applikationen för ett specifikt kort, men detta är en storleksordning mindre signifikant än utvecklingen av en algoritm för GPU-arkitekturen i princip.

Radeon 47xx-seriens begränsningar

I den här familjen är stödet för GPU-beräkning ofullständigt. Tre viktiga punkter kan noteras. För det första finns det inget lokalt minne, det vill säga det finns fysiskt där, men det har inte den universella åtkomst som krävs av den moderna standarden för GPU-program. Den emuleras i mjukvara i globalt minne, vilket innebär att dess användning, till skillnad från en fullfjädrad GPU, inte kommer att ge fördelar. Den andra punkten är det begränsade stödet för olika operationsinstruktioner för atomminne och synkroniseringsinstruktioner. Och den tredje punkten är den ganska lilla storleken på instruktionscachen: från en viss programstorlek saktar hastigheten ner avsevärt. Det finns andra mindre begränsningar. Vi kan säga att endast program som är idealiska för GPU:n kommer att fungera bra på detta grafikkort. Även om ett grafikkort i enkla testprogram som endast fungerar med register kan visa bra resultat i Gigaflops, är det problematiskt att effektivt programmera något komplext för det.

Fördelar och nackdelar med Evergreen

Om du jämför AMD- och Nvidia-produkter, ur ett GPU-datorperspektiv, ser 5xxx-serien ut som en mycket kraftfull GT200. Så kraftfull att den överträffar Fermi i toppprestanda med ungefär två och en halv gånger. Speciellt efter att parametrarna för de nya Nvidia-grafikkorten skars ner och antalet kärnor minskat. Men introduktionen av en L2-cache i Fermi förenklar implementeringen av vissa algoritmer på GPU:n, vilket utökar omfattningen av GPU:n. Intressant nog, för CUDA-program väl optimerade för den tidigare generationen av GT200, gjorde Fermis arkitektoniska innovationer ofta ingenting. De accelererade i proportion till ökningen av antalet beräkningsmoduler, det vill säga mindre än två gånger (för enkelprecisionsnummer), eller ännu mindre, eftersom minnesbandbredden inte ökade (eller av andra skäl).

Och i uppgifter som är väl lämpade för GPU-arkitekturen och har en uttalad vektornatur (till exempel matrismultiplikation) visar Radeon prestanda relativt nära den teoretiska toppen och överträffar Fermi. För att inte tala om flerkärniga processorer. Särskilt i problem med enstaka precisionsnummer.

Men Radeon har en mindre formarea, mindre värmeavledning, strömförbrukning, högre utbyte och följaktligen lägre kostnad. Och direkt i 3D-grafikuppgifter är Fermis vinst, om den överhuvudtaget finns, mycket mindre än skillnaden i kristallytan. Detta beror till stor del på att Radeons datorarkitektur med 16 beräkningsenheter per miniprocessor, en vågfrontstorlek på 64 trådar och VLIW-vektorinstruktioner är utmärkt för sin huvuduppgift - datorgrafikskuggning. För de allra flesta vanliga användare är spelprestanda och pris prioriterade.

Ur ett professionellt, vetenskapligt mjukvaruperspektiv ger Radeon-arkitekturen bästa pris-prestanda, prestanda per watt och absolut prestanda för uppgifter som i sig är väl matchade med GPU-arkitekturer, vilket möjliggör parallellisering och vektorisering.

Till exempel, i en helt parallell, lätt vektoriserbar nyckelvalsuppgift är Radeon flera gånger snabbare än GeForce och flera tiotals gånger snabbare än CPU.

Detta överensstämmer med det allmänna konceptet för AMD Fusion, enligt vilket GPU:er ska komplettera processorn och i framtiden integreras i själva processorkärnan, precis som den matematiska samprocessorn tidigare flyttades från ett separat chip till processorkärnan (denna hände för tjugo år sedan, innan de första Pentium-processorerna dök upp). GPU:n kommer att vara en integrerad grafikkärna och vektorsamprocessor för streaminguppgifter.

Radeon använder en smart teknik för att blanda instruktioner från olika vågfronter när de exekveras av funktionsmoduler. Detta är lätt att göra eftersom instruktionerna är helt oberoende. Principen liknar den pipelinerade exekveringen av oberoende instruktioner av moderna processorer. Uppenbarligen gör detta det möjligt att effektivt exekvera komplexa, multi-byte vektor VLIW instruktioner. I en CPU kräver detta en sofistikerad schemaläggare för att identifiera oberoende instruktioner eller användning av Hyper-Threading-teknologi, som också förser CPU:n med avsiktligt oberoende instruktioner från olika trådar.

mäta 0stapel 1åtgärd 2åtgärd 3stapel 4stapel 5takt 6stapel 7VLIW-modul
vågfront 0vågfront 1vågfront 0vågfront 1vågfront 0vågfront 1vågfront 0vågfront 1
instr. 0instr. 0instr. 16instr. 16instr. 32instr. 32instr. 48instr. 48VLIW0
instr. 1VLIW1
instr. 2VLIW2
instr. 3VLIW3
instr. 4VLIW4
instr. 5VLIW5
instr. 6VLIW6
instr. 7VLIW7
instr. 8VLIW8
instr. 9VLIW9
instr. 10VLIW10
instr. elvaVLIW11
instr. 12VLIW12
instr. 13VLIW13
instr. 14VLIW14
instr. 15VLIW15

128 instruktioner av två vågfronter, som var och en består av 64 operationer, exekveras av 16 VLIW-moduler i åtta klockcykler. Interfoliering inträffar och varje modul har i verkligheten två klockcykler för att exekvera en hel instruktion, förutsatt att den på den andra klockcykeln börjar exekvera en ny parallellt. Detta hjälper förmodligen till att snabbt exekvera en VLIW-instruktion som a1×a2+b1×b2+c1×c2+d1×d2, det vill säga exekvera åtta sådana instruktioner i åtta klockcykler. (Formellt visar det sig vara en per åtgärd.)

Nvidia har tydligen inte sådan teknik. Och i avsaknad av VLIW kräver hög prestanda med hjälp av skalära instruktioner högfrekvent drift, vilket automatiskt ökar värmeavledningen och ställer höga krav på processen (för att tvinga kretsen att arbeta med en högre frekvens).

Nackdelen med Radeon ur GPU-beräkningssynpunkt är dess stora motvilja mot förgrening. GPU:er föredrar i allmänhet inte förgrening på grund av tekniken som beskrivs ovan för att utföra instruktioner: på en gång i en grupp av trådar med en programadress. (Förresten, den här tekniken kallas SIMT: Single Instruction - Multiple Threads (en instruktion - många trådar), i analogi med SIMD, där en instruktion utför en operation med olika data.) Radeon gillar dock inte särskilt förgrening: detta orsakas av den större storleken på trådbunten. Det är tydligt att om programmet inte är helt vektormässigt, så är ju större storleken på varpen eller vågfronten, desto värre, eftersom när angränsande trådar divergerar i sina programvägar, bildas fler grupper som måste exekveras sekventiellt (serialiserad). Låt oss säga att alla trådar är utspridda, om varpstorleken är 32 trådar kommer programmet att arbeta 32 gånger långsammare. Och i fallet med storlek 64, som i Radeon, är den 64 gånger långsammare.

Detta är en märkbar, men inte den enda manifestationen av "fientlighet". I Nvidia grafikkort har varje funktionsmodul, annars kallad CUDA-kärnan, en speciell filialbehandlingsenhet. Och i Radeon grafikkort med 16 beräkningsmoduler finns det bara två grenstyrenheter (de tas bort från domänen för aritmetiska enheter). Så även enkel bearbetning av en villkorlig hoppinstruktion, även om dess resultat är detsamma för alla trådar i vågfronten, tar ytterligare tid. Och hastigheten sjunker.

AMD producerar också processorer. De menar att för program med ett stort antal grenar är CPU:n fortfarande bättre lämpad, medan GPU:n är avsedd för rena vektorprogram.

Så Radeon ger mindre övergripande programmeringseffektivitet, men ger bättre pris/prestanda i många fall. Det finns med andra ord färre program som effektivt (lönsamt) kan migreras från en CPU till en Radeon än det finns program som kan köras effektivt på Fermi. Men de som effektivt kan överföras kommer att fungera mer effektivt på Radeon på många sätt.

API för GPU-datorer

De tekniska specifikationerna för Radeon själva ser attraktiva ut, även om det inte finns något behov av att idealisera och absolutisera GPU-beräkningar. Men inte mindre viktig för produktiviteten är programvaran som är nödvändig för att utveckla och köra ett GPU-program - kompilatorer från ett högnivåspråk och körtid, det vill säga en drivrutin som interagerar mellan den del av programmet som körs på CPU:n och GPU:n sig. Det är ännu viktigare än i fallet med en CPU: CPU:n behöver ingen drivrutin för att hantera dataöverföringar, och från kompilatorns synvinkel är GPU:n mer petig. Till exempel måste kompilatorn nöja sig med ett minsta antal register för att lagra mellanliggande resultat av beräkningar, och även noggrant integrera funktionsanrop, återigen med ett minimum av register. När allt kommer omkring, ju färre register en tråd använder, desto fler trådar kan startas och desto mer fullständigt kan GPU:n laddas, desto bättre döljer minnesåtkomsttiden.

Och mjukvarustöd för Radeon-produkter släpar fortfarande efter hårdvaruutvecklingen. (Till skillnad från situationen med Nvidia, där utgivningen av hårdvara försenades och produkten släpptes i en avskalad form.) Nyligen hade OpenCL-kompilatorn som producerats av AMD betastatus, med många brister. Den genererade felaktig kod för ofta, eller vägrade att kompilera kod från rätt källkod, eller så producerade den själv ett fel och kraschade. Först i slutet av våren släpptes en release med hög prestanda. Det är inte heller utan fel, men det är betydligt färre av dem, och de tenderar att uppstå i sidled när man försöker programmera något på gränsen till korrekthet. Till exempel arbetar de med typen uchar4, som definierar en 4-byte fyrkomponentsvariabel. Den här typen finns i OpenCL-specifikationerna, men det är inte värt att arbeta med det på Radeon, eftersom registren är 128-bitars: samma fyra komponenter, men 32-bitars. Och en sådan uchar4-variabel kommer fortfarande att uppta ett helt register, den kommer bara att kräva ytterligare packningsoperationer och tillgång till enskilda bytekomponenter. Kompilatorn ska inte ha några fel, men det finns inga kompilatorer utan brister. Även Intel Compiler efter 11 versioner har kompileringsfel. De identifierade felen korrigeras i nästa release, som kommer att släppas närmare hösten.

Men det finns fortfarande många saker som behöver förbättras. Till exempel stöder standard Radeon GPU-drivrutinen fortfarande inte GPU-beräkning med OpenCL. Användaren måste ladda ner och installera ytterligare ett specialpaket.

Men det viktigaste är frånvaron av funktionsbibliotek. För reella tal med dubbel precision finns det inte ens en sinus, cosinus eller exponent. Tja, detta krävs inte för matrisaddition och multiplikation, men om du vill programmera något mer komplext måste du skriva alla funktioner från början. Eller vänta på en ny SDK-version. ACML (AMD Core Math Library) för Evergreen GPU-familjen med stöd för grundläggande matrisfunktioner bör snart släppas.

För närvarande, enligt artikelförfattaren, verkar användningen av Direct Compute 5.0 API realistisk för programmering av Radeon grafikkort, naturligtvis med hänsyn till begränsningarna: fokus på Windows-plattform 7 och Windows Vista. Microsoft har lång erfarenhet av att skapa kompilatorer, och vi kan förvänta oss en fullt fungerande release mycket snart, Microsoft är direkt intresserade av detta. Men Direct Compute är fokuserad på behoven hos interaktiva applikationer: att beräkna något och omedelbart visualisera resultatet - till exempel flödet av vätska över en yta. Detta betyder inte att det inte kan användas enbart för beräkningar, men det är inte dess naturliga syfte. Låt oss säga att Microsoft inte planerar att lägga till biblioteksfunktioner till Direct Compute - bara de som AMD inte har för närvarande. Det vill säga att det som nu effektivt kan beräknas på Radeon – vissa inte särskilt sofistikerade program – kan också implementeras på Direct Compute, vilket är mycket enklare än OpenCL och borde vara mer stabilt. Dessutom är den helt portabel och kommer att köras på både Nvidia och AMD, så du behöver bara kompilera programmet en gång, medan Nvidia och AMD:s OpenCL SDK-implementeringar inte är helt kompatibla. (I den meningen att om du utvecklar ett OpenCL-program på ett AMD-system med AMD OpenCL SDK, kanske det inte körs lika lätt på Nvidia. Du kan behöva kompilera samma text med Nvidia SDK. Och, naturligtvis, vice versa .)

Sedan finns det mycket redundant funktionalitet i OpenCL, eftersom OpenCL är tänkt att vara ett universellt programmeringsspråk och API för ett brett spektrum av system. Och GPU, och CPU och Cell. Så om du bara behöver skriva ett program för ett typiskt användarsystem (processor plus grafikkort), verkar OpenCL inte vara "högproduktiv", så att säga. Varje funktion har tio parametrar, och nio av dem måste ställas in på 0. Och för att ställa in varje parameter måste du anropa speciell funktion, som också har parametrar.

Och den viktigaste nuvarande fördelen med Direct Compute är att användaren inte behöver installera ett speciellt paket: allt som behövs finns redan i DirectX 11.

Problem med GPU-datorutveckling

Om vi ​​tar sfären med persondatorer är situationen denna: det finns inte många uppgifter som kräver stor datorkraft och en konventionell dual-core processor saknas i hög grad. Det var som om stora, glupska men klumpiga monster hade krupit upp ur havet till land, och det fanns nästan ingenting att äta på land. Och de ursprungliga boningarna på jordens yta minskar i storlek och lär sig att konsumera mindre, som alltid händer när det råder brist på naturresurser. Om det fanns samma behov av prestanda nu som för 10-15 år sedan skulle GPU-beräkning vara en stor hit. Och så kommer problemen med kompatibilitet och den relativa komplexiteten i GPU-programmering i förgrunden. Det är bättre att skriva ett program som körs på alla system än ett program som körs snabbt men bara körs på GPU.

Utsikterna för GPU:er är något bättre när det gäller användning i professionella applikationer och arbetsstationssektorn, eftersom det finns ett större behov av prestanda där. Det finns plugins för 3D-redigerare med GPU-stöd: till exempel för rendering med ray tracing - inte att förväxla med vanlig GPU-rendering! Något håller också på att dyka upp för 2D- och presentationsredigerare, med snabbare skapande av komplexa effekter. Videobehandlingsprogram får också gradvis GPU-stöd. Ovanstående uppgifter, på grund av sin parallella karaktär, passar bra med GPU-arkitekturen, men nu har en mycket stor kodbas skapats, felsökt och optimerats för alla kapaciteter hos CPU:n, så det kommer att ta tid för bra GPU-implementationer att dyka upp .

I detta segment finns också sådana svaga sidor GPU:er har en begränsad mängd videominne - cirka 1 GB för vanliga GPU:er. En av huvudfaktorerna som minskar prestanda hos GPU-program är behovet av att utbyta data mellan CPU och GPU över en långsam buss, och på grund av begränsat minne måste mer data överföras. Och här ser AMD:s koncept att kombinera GPU och CPU i en modul lovande ut: du kan offra den höga bandbredden på grafikminnet för lättvikts- och lätt tillgång till delat minne, även med lägre latens. Denna höga bandbredd på nuvarande DDR5-videominne efterfrågas mycket mer direkt från grafikprogram än från de flesta GPU-datorprogram. I allmänhet kommer det delade minnet för GPU:n och CPU:n helt enkelt att avsevärt utöka omfattningen av GPU:n, vilket gör det möjligt att använda dess beräkningskapacitet i små deluppgifter av program.

Och GPU:er är mest efterfrågade inom området för vetenskaplig datoranvändning. Flera GPU-baserade superdatorer har redan byggts, som visar mycket höga resultat i matrisoperationstestet. Vetenskapliga problem är så olika och många att det alltid finns många som passar perfekt in i GPU-arkitekturen, för vilka användningen av en GPU gör det enkelt att få hög prestanda.

Om du väljer en bland alla moderna datorers uppgifter blir det datorgrafik - bilden av den värld vi lever i. Och den optimala arkitekturen för detta ändamål kan inte vara dålig. Detta är en så viktig och grundläggande uppgift att hårdvara speciellt utformad för den måste vara universell och optimal för olika uppgifter. Dessutom utvecklas grafikkort framgångsrikt.

En av de mest dolda funktionerna på senare tid Windows uppdatering 10, är ​​möjligheten att kontrollera vilka applikationer som använder din grafikprocessorenhet (GPU). Om du någonsin har öppnat Aktivitetshanteraren har du förmodligen tittat på din CPU-användning för att se vilka appar som använder mest CPU. I senaste uppdateringarna lagt till en liknande funktion, men för GPU-grafikprocessorer. Detta hjälper dig att förstå hur intensiv programvara och spel är på din GPU utan att behöva ladda ner programvara från tredje part. Det finns en annan intressant funktion som hjälper till att ladda ner din CPU till GPU:n. Jag rekommenderar att läsa hur man väljer.

Varför har jag inte GPU i Aktivitetshanteraren?

Tyvärr kommer inte alla grafikkort att kunna tillhandahålla Windows-system statistik som behövs för att läsa GPU:n. För att vara säker kan du snabbt använda diagnostikverktyget DirectX för att kontrollera denna teknik.

  1. Klick " Start" och skriv i sökningen dxdiag för att köra DirectX Diagnostic Tool.
  2. Gå till "fliken" Skärm", till höger i kolumnen " förare"du måste ha WDDM-modell mer än 2.0 version för att använda GPU-grafer i Aktivitetshanteraren.

Aktivera GPU-graf i Aktivitetshanteraren

För att se GPU-användningen för varje applikation måste du öppna aktivitetshanteraren.

  • Tryck på en kombination av knappar Ctrl + Shift + Esc för att öppna aktivitetshanteraren.
  • Högerklicka i aktivitetshanteraren på den "tomma" rutan Namn" och kontrollera från rullgardinsmenyn GPU Du kan också notera GPU kärna för att se vilka program som använder den.
  • Nu i aktivitetshanteraren är GPU-grafen och GPU-kärnan synliga till höger.


Se övergripande GPU-prestanda

Du kan övervaka den totala GPU-användningen för att övervaka den under tung belastning och analysera den. I det här fallet kan du se allt du behöver på fliken " Prestanda" genom att välja grafikprocessor.


Varje GPU-element är uppdelat i individuella grafer för att ge dig ännu mer insikt i hur din GPU används. Om du vill ändra graferna som visas kan du klicka på den lilla pilen bredvid namnet på varje uppgift. Den här skärmen visar också din drivrutinsversion och datum, vilket är ett bra alternativ till att använda DXDiag eller Enhetshanteraren.


Vilket program behövs för att bryta kryptovaluta? Vad ska man tänka på när man väljer gruvutrustning? Hur man bryter Bitcoin och Ethereum med ett grafikkort på en dator?

Det visar sig att kraftfulla grafikkort behövs inte bara av fans av spektakulära datorspel. Tusentals användare runt om i världen använder grafikadaptrar för att tjäna kryptovaluta! Från flera kort med kraftfulla processorer gruvarbetare skapa gårdar– datorcenter som utvinner digitala pengar praktiskt taget ur tomma luften!

Denis Kuderin är med dig, en expert på tidningen HeatherBober i frågor om ekonomi och deras kompetenta multiplikation. Jag ska berätta vad det är mining på ett grafikkort i 17-18, hur man väljer rätt enhet för att tjäna kryptovaluta och varför brytning av bitcoins på grafikkort inte längre är lönsamt.

Det får du också reda på var man kan köpa det mest produktiva och kraftfulla grafikkortet för professionell gruvdrift och få expertråd om hur du kan förbättra effektiviteten hos din gruvrigg.

1. Mining på ett grafikkort - lätta pengar eller omotiverade utgifter

Ett bra grafikkort är inte bara en adapter digitala signaler, men också kraftfull processor, kapabel att lösa komplexa beräkningsproblem. Och inklusive - beräkna en hash-kod för en blockkedja (blockchain). Detta gör grafikkort till det perfekta verktyget för brytning– brytning av kryptovaluta.

Fråga: Varför en grafikkortsprocessor? Det har ju varje dator CPU? Är det inte logiskt att göra beräkningar med det?

Svar: CPU-processorn kan också beräkna blockkedjor, men den gör det hundratals gånger långsammare än en grafikkortsprocessor (GPU). Och inte för att det ena är bättre, det andra är sämre. De har bara olika funktionsprinciper. Och om du kombinerar flera grafikkort kommer kraften hos ett sådant datorcenter att öka flera gånger mer.

För den som inte har en aning om hur digitala pengar utvinns, ett litet utbildningsprogram. Gruvdrift – det viktigaste, och ibland det enda sättet att producera kryptovaluta.

Eftersom ingen präglar eller trycker dessa pengar, och det inte är en materiell substans, utan en digital kod, måste någon beräkna denna kod. Detta är vad gruvarbetare gör, eller snarare, deras datorer gör.

Förutom kodberäkningar utför gruvdrift flera viktigare uppgifter:

  • stöd för systemdecentralisering: brist på anknytning till servrar är grunden för blockkedjan;
  • transaktionsbekräftelse– utan gruvdrift kommer verksamheten inte att kunna gå in i ett nytt block;
  • bildandet av nya block av systemet– och föra in dem i ett enda register för alla datorer.

Jag skulle vilja omedelbart kyla ner iver hos nybörjare gruvarbetare: gruvprocessen blir svårare och svårare för varje år. Att till exempel använda ett grafikkort har länge varit olönsamt.

Endast inbitna amatörer bryter nu köbollar med GPU:er, eftersom grafikkort har ersatts av specialiserade processorer ASIC. Dessa chips förbrukar mindre ström och är mer beräkningseffektiva. Alla är bra, men de kostar ungefär en storleksordning 130-150 tusen rubel .

Kraftfull modell Antminer S9

Lyckligtvis för gruvarbetare är Bitcoin inte den enda kryptovalutan på planeten, utan en av hundratals. Andra digitala pengar – Ethereum, Zcash, Expanse, dogecoins etc. Det är fortfarande lönsamt att bryta med grafikkort. Ersättningen är stabil och utrustningen betalar sig själv på cirka 6-12 månader.

Men det finns ett annat problem - bristen på kraftfulla grafikkort.. Hypen kring kryptovaluta har lett till en ökning av priset på dessa enheter. Att köpa ett nytt grafikkort som är lämpligt för gruvdrift i Ryssland är inte så lätt.

Nybörjare måste beställa videoadaptrar från onlinebutiker (inklusive utländska) eller köpa begagnade varor. Förresten, jag rekommenderar inte att du gör det senare: gruvutrustning håller på att bli föråldrad och slits ut i en fantastisk takt.

På Avito säljer de till och med hela gårdar för brytning av kryptovaluta.

Det finns många anledningar: vissa gruvarbetare har redan "spelat tillräckligt" för att bryta digitala pengar och beslutat sig för att engagera sig i mer lönsamma operationer med kryptovaluta (i synnerhet valutahandel), andra insåg att de inte kunde konkurrera med kraftfulla kinesiska kluster som verkar på basen för kraftverk. Ytterligare andra bytte från grafikkort till ASIC.

Nischen ger dock fortfarande en viss vinst, och om du börjar använda ett grafikkort just nu har du fortfarande tid att hoppa på tåget som går för framtiden.

En annan sak är att det finns fler och fler spelare på det här fältet. Dessutom ökar inte det totala antalet digitala mynt från detta. Tvärtom blir belöningen mindre.

Så för sex år sedan var belöningen för en blockchain i Bitcoin-nätverket lika med 50 mynt, nu är det bara 12,5 BTK. Komplexiteten i beräkningarna har ökat 10 tusen gånger. Det är sant att värdet på själva Bitcoin har ökat många gånger under den här tiden.

2. Hur man bryter kryptovaluta med ett grafikkort - steg-för-steg-instruktioner

Det finns två gruvalternativ - solo och som en del av en pool. Det är svårt att göra solo mining - du behöver ha en enorm mängd hashrat(effektenheter) så att de påbörjade beräkningarna har en sannolikhet för framgångsrikt slutförande.

99% av alla gruvarbetare arbetar i pooler(Engelsk pool – pool) – samhällen som är engagerade i distributionen av datoruppgifter. Gemensam gruvdrift eliminerar slumpfaktorn och garanterar stabila vinster.

En gruvarbetare jag känner sa detta om detta: Jag har brytit i 3 år, under vilken tid jag inte har kommunicerat med någon som brytit ensam.

Sådana prospektörer liknar guldgruvarbetarna på 1800-talet. Du kan söka i flera år efter din guldklimp (i vårt fall, Bitcoin) och fortfarande inte hitta den. Det vill säga blockkedjan kommer aldrig att stängas, vilket innebär att du inte får någon belöning.

"Lonely hunters" har något bättre chanser för eter och några andra kryptomynt.

På grund av den unika krypteringsalgoritmen bryts inte ETH med hjälp av speciella processorer (de har ännu inte uppfunnits). Endast grafikkort används för detta. Många bönder i vår tid överlever fortfarande på bekostnad av Ethereum och andra altcoins.

Ett grafikkort räcker inte för att skapa en fullfjädrad gård: 4 stycken – "levnadslön" för en gruvarbetare räkna med stabila vinster. Lika viktigt är ett kraftfullt kylsystem för videoadaptrar. Och glöm inte bort en sådan utgiftspost som elräkningar.

Steg-för-steg-instruktioner kommer att skydda dig från misstag och påskynda processinställningen.

Steg 1. Välj en pool

Världens största kryptovalutapooler finns i Kina, samt på Island och USA. Formellt har dessa samhällen ingen statlig tillhörighet, men ryskspråkiga poolsajter är en sällsynthet på Internet.

Eftersom du med största sannolikhet kommer att behöva bryta Ethereum på ett grafikkort, måste du välja den community som är involverad i att beräkna denna valuta. Även om Ethereum är ett relativt ungt altcoin, det finns många pooler för dess gruvdrift. Storleken på din inkomst och dess stabilitet beror till stor del på valet av gemenskap.

Vi väljer en pool utifrån följande kriterier:

  • prestanda;
  • arbetstimmar;
  • berömmelse bland kryptovalutagruvarbetare;
  • närvaro av positiva recensioner på oberoende forum;
  • bekvämligheten med att ta ut pengar;
  • provisionsstorlek;
  • principen för vinstberäkning.

Förändringar sker dagligen på kryptovalutamarknaden. Detta gäller även växelkurshopp och uppkomsten av nya digitala pengar - gafflar bitcoin. Globala förändringar sker också.

Således blev det nyligen känt att eter inom en snar framtid kommer att övergå till ett fundamentalt annorlunda system för vinstutdelning. I ett nötskal, inkomster i Etherium-nätverket kommer att tjänas av gruvarbetare som har "mycket ketse", det vill säga mynt, och nybörjare måste antingen stänga butiken eller byta till andra pengar.

Men sådana "småsaker" stoppade aldrig entusiaster. Dessutom finns det ett program som heter Profitable Pool. Den spårar automatiskt de mest lönsamma altcoins att bryta för tillfället. Det finns också en söktjänst för själva poolerna, samt deras betyg i realtid.

Steg 2. Installera och konfigurera programmet

Efter att du har registrerat dig på poolwebbplatsen måste du ladda ner ett speciellt minerprogram - beräkna inte koden manuellt med hjälp av en miniräknare. Det finns också tillräckligt med sådana program. För Bitcoin är detta - 50 gruvarbetare eller CGMiner, för sändning – Etminer.

Att sätta upp kräver omsorg och viss kompetens. Du behöver till exempel veta vad skript är och kunna passa in dem kommandorad din dator. Tekniska punkter Jag råder dig att kolla med praktiserande gruvarbetare, eftersom varje program har sina egna installations- och konfigurationsnyanser.

Steg 3. Registrera plånboken

Om du ännu inte har en Bitcoin-plånbok eller Ethereum-lagring måste du registrera dem. Vi laddar ner plånböcker från officiella webbplatser.

Ibland tillhandahåller poolerna själva hjälp i denna fråga, men inte gratis.

Steg 4. Starta gruvdrift och övervaka statistik

Allt som återstår är att starta processen och vänta på de första kvittonen. Se till att ladda ner ett hjälpprogram som övervakar statusen för huvudkomponenterna i din dator - belastning, överhettning etc.

Steg 5. Ta ut kryptovaluta

Datorer arbetar dygnet runt och automatiskt, beräknar kod. Allt du behöver göra är att se till att korten eller andra system inte misslyckas. Kryptovaluta kommer att flöda in i din plånbok med en hastighet som är direkt proportionell mot mängden hashrate.

Hur konverterar man digital valuta till fiatvaluta? En fråga som är värd en separat artikel. Kort sagt, det mesta snabbt sätt- växlingskontor. De tar en procentsats för sina tjänster, och din uppgift är att hitta den mest lönsamma räntan med lägsta provision. En professionell jämförelsetjänst för växlare hjälper dig att göra detta.

– den bästa resursen av detta slag i RuNet. Denna övervakning jämför prestandan för mer än 300 växlingskontor och hittar de bästa kurserna för de valutapar du är intresserad av. Dessutom indikerar tjänsten kryptovalutareserver i kassaregistret. Övervakningslistorna innehåller endast beprövade och pålitliga utbytestjänster.

3. Vad du ska titta efter när du väljer ett grafikkort för gruvdrift

Du måste välja ett grafikkort klokt. Den första du stöter på eller den som redan finns på din dator kommer också att min, men denna kraft kommer att vara försumbar även för etrar.

Huvudindikatorerna är följande: prestanda (kraft), strömförbrukning, kylning, överklockningsmöjligheter.

1) Kraft

Allt är enkelt här - ju högre processorprestanda, desto bättre för att beräkna hashkoden. Utmärkt prestanda tillhandahålls av kort med en minneskapacitet på mer än 2 GB. Och välj enheter med en 256-bitars buss. 128-bitar är inte lämpliga för detta ändamål.

2) Strömförbrukning

Makt är förstås stor - hög hashrate och allt det där. Men glöm inte energiförbrukningsindikatorer. Vissa produktiva gårdar "äter upp" så mycket el att kostnaderna knappt får tillbaka eller inte alls.

3) Kylning

Standarden består av 4-16 kort. Det producerar en överdriven mängd värme, vilket är skadligt för järnet och oönskat för bonden själv. Att bo och arbeta i en ettrumslägenhet utan luftkonditionering kommer att vara milt uttryckt obehagligt.

Högkvalitativ processorkylning är en oumbärlig förutsättning för framgångsrik gruvdrift

Därför, när du väljer två kort med samma prestanda, ge företräde åt det med mindre termisk effektindikator (TDP) . De bästa kylningsparametrarna visas av Radeon-kort. Samma enheter fungerar längre än alla andra kort i aktivt läge utan slitage.

Ytterligare kylare tar inte bara bort överskottsvärme från processorer, utan förlänger också deras livslängd.

4) Överklockningsförmåga

Överklockning är en påtvingad ökning av ett grafikkorts prestanda. Möjligheten att "överklocka kortet" beror på två parametrar – GPU-frekvenser och videominnesfrekvenser. Det är dessa du kommer att överklocka om du vill öka datorkraften.

Vilka grafikkort ska jag skaffa? Du behöver enheter senaste generationen eller åtminstone grafikacceleratorer som släpptes tidigast för 2-3 år sedan. Gruvarbetare använder kort AMD Radeon, Nvidia, GeForce GTX.

Ta en titt på återbetalningstabellen för grafikkort (data är aktuella i slutet av 2017):

4. Var man kan köpa ett grafikkort för gruvdrift – genomgång av TOP 3-butikerna

Som jag redan sa, med gruvdriftens växande popularitet har grafikkort blivit en bristvara. Att köpa önskad enhet, kommer du att behöva spendera mycket tid och ansträngning.

Vår recension hjälper dig bästa poängen onlineförsäljning.

1) TopComputer

Moskvas stormarknad specialiserad på datorer och hushållsapparater. Det har funnits på marknaden i mer än 14 år och levererat varor från hela världen till nästan tillverkarpriser. Det finns en snabb leveransservice, gratis för muskoviter.

I skrivande stund finns det kort på rea AMD, Nvidia(8 Gb) och andra sorter lämpliga för gruvdrift.

2) Mybitcoinshop

Specialaffär, handel uteslutande med varor för gruvdrift. Här hittar du allt du behöver för att bygga en hemgård - grafikkort med den nödvändiga konfigurationen, strömförsörjning, adaptrar och till och med ASIC-gruvarbetare (för nya generationens gruvarbetare). Det finns en betald leverans och hämtning från ett lager i Moskva.

Företaget har upprepade gånger fått den inofficiella titeln på den bästa butiken för gruvarbetare i Ryska federationen. Snabb service, vänlig attityd mot kunder, avancerad utrustning är huvudkomponenterna för framgång.

3) Ship Shop America

Inköp och leverans av varor från USA. Ett mellanhandsföretag för dig som behöver verkligt exklusiva och banbrytande gruvprodukter.

Direkt partner till den ledande tillverkaren av grafikkort för spel och gruvdrift – Nvidia. Den maximala väntetiden för varor är 14 dagar.

5. Hur man ökar inkomsten från gruvdrift på ett grafikkort - 3 användbara tips

Otåliga läsare som vill börja bryta just nu och få inkomst från och med i morgon bitti kommer säkert att fråga - hur mycket tjänar gruvarbetare?

Intäkterna beror på utrustningen, kryptovalutakursen, poolens effektivitet, gårdens kraft, hashrate och en massa andra faktorer. Vissa lyckas ta emot upp till månadsvis 70 000 rubel , andra är nöjda 10 dollar i vecka. Det här är en instabil och oförutsägbar verksamhet.

Användbara tips hjälper dig att öka din inkomst och optimera dina utgifter.

Om du bryter en valuta som snabbt växer i pris kommer du att tjäna mer. Till exempel kostar eter nu ca 300 dollar, Bitcoin – mer 6000 . Men du måste ta hänsyn till inte bara det aktuella värdet, utan också tillväxttakten under veckan.

Tips 2. Använd en gruvkalkylator för att välja den optimala hårdvaran

En gruvkalkylator på en poolwebbplats eller annan specialiserad tjänst hjälper dig att välja det optimala programmet och till och med ett grafikkort för gruvdrift.

Det kan aldrig bli för många kärnor...

Moderna grafikprocessorer är monstruösa, snabba bestar som kan tugga gigabyte med data. Men människan är listig och oavsett hur mycket datorkraften växer så kommer hon med fler och mer komplexa problem, så ögonblicket kommer då vi tyvärr måste erkänna att optimering behövs 🙁

Den här artikeln beskriver de grundläggande begreppen för att göra det lättare att navigera i teorin om gpu-optimering och de grundläggande reglerna så att dessa begrepp måste behandlas mer sällan.

Anledningar till varför GPU:er är effektiva för att arbeta med stora mängder data som kräver bearbetning:

  • de har stor kapacitet för parallell exekvering av uppgifter (många, många processorer)
  • hög minnesbandbredd

Minnesbandbredd- det här är hur mycket information - en bit eller en gigabyte - kan överföras per tidsenhet - en sekund eller en processorcykel.

En av optimeringsuppgifterna är att använda maximal genomströmning – för att öka prestandan genomströmning(helst bör det vara lika med minnesbandbredd).

För att förbättra bandbreddsutnyttjandet:

  • öka mängden information - använd bandbredden till fullo (till exempel, varje stream fungerar med float4)
  • minska latens – fördröjning mellan operationer

Latens– Tidsperioden mellan de ögonblick då den registeransvarige begärde en specifik minnescell och det ögonblick då uppgifterna blev tillgängliga för processorn för att utföra instruktioner. Vi kan inte påverka själva fördröjningen på något sätt - dessa begränsningar finns på hårdvarunivå. Det är på grund av denna fördröjning som processorn samtidigt kan betjäna flera trådar - medan tråd A har begärt att allokera minne till den kan tråd B beräkna något och tråd C kan vänta tills den begärda datan kommer till den.

Hur man minskar latensen om synkronisering används:

  • minska antalet trådar i ett block
  • öka antalet blockgrupper

Full användning av GPU-resurser – GPU Occupancy

I högpanna samtal om optimering dyker termen ofta upp - gpu-beläggning eller kärnan beläggning– det återspeglar effektiviteten i att använda grafikkortets resurser. Jag vill separat notera att även om du använder alla resurser så betyder det inte att du använder dem korrekt.

Datorkraften hos GPU:n är hundratals beräkningshungriga processorer när man skapar ett program - kärnan - bördan av att fördela belastningen faller på programmerarens axlar. Ett misstag kan leda till att mycket av dessa värdefulla resurser står stilla. Nu ska jag förklara varför. Vi måste börja på långt håll.

Låt mig påminna dig om den varpen ( varp i NVidia terminologi, vågfront – i AMD-terminologi) är en uppsättning trådar som samtidigt utför samma kärnfunktion på processorn. Trådar som förenas av programmeraren i block delas upp i varps av en trådschemaläggare (separat för varje multiprocessor) - medan en warp fungerar väntar den andra på att bearbeta minnesförfrågningar, etc. Om några av varptrådarna fortfarande utför beräkningar, medan andra redan har gjort allt de kunnat, finns det en ineffektiv användning av beräkningsresursen – populärt kallad ledig kapacitet.

Varje synkroniseringspunkt, varje logikgren kan generera en sådan ledig situation. Den maximala divergensen (förgrening av exekveringslogik) beror på varpens storlek. För NVidia GPU:er är det 32, för AMD är det 64.

Så här minskar du nedtid för flera processorer under körning av warp:

  • minimera barriärens väntetid
  • minimera divergensen av exekveringslogik i kärnfunktionen

För effektiv lösning För detta problem är det vettigt att ta reda på hur varpar bildas (för fallet med flera dimensioner). Faktum är att ordningen är enkel - först i X, sedan i Y och slutligen i Z.

kärnan lanseras med block i storleken 64x16, trådar är uppdelade i varp i ordningen X, Y, Z - d.v.s. de första 64 elementen är uppdelade i två varpar, sedan den andra osv.

Kärnan körs med 16x64 block. De första och andra 16 elementen läggs till den första varpen, den tredje och fjärde - till den andra varpen, etc.

Hur man minskar divergensen (kom ihåg att förgrening inte alltid är orsaken till kritisk prestandaförlust)

  • när intilliggande flöden har olika exekveringsvägar - det finns många förhållanden och övergångar längs dem - leta efter sätt att omstrukturera
  • leta efter en obalanserad belastning av trådar och bestämt ta bort den (det är när vi inte bara har villkor, utan på grund av dessa förhållanden beräknar den första tråden alltid något, och den femte uppfyller inte detta villkor och är inaktiv)

Hur du får ut det mesta av dina GPU-resurser

GPU-resurser har tyvärr också sina begränsningar. Och strängt taget, innan du startar kärnfunktionen, är det vettigt att bestämma gränserna och ta hänsyn till dessa gränser när belastningen distribueras. Varför är det viktigt?

Grafikkort har begränsningar för det totala antalet trådar som en multiprocessor kan köra, det maximala antalet trådar i ett block, det maximala antalet warps på en processor, begränsningar för olika typer av minne, etc. All denna information kan begäras antingen programmatiskt, genom lämpligt API, eller tidigare med hjälp av verktyg från SDK. (deviceQuery-moduler för NVidia-enheter, CLInfo - för AMD-grafikkort).

Allmän praktik:

  • antalet trådblock/arbetsgrupper måste vara en multipel av antalet strömprocessorer
  • block/arbetsgruppsstorlek måste vara en multipel av varpstorleken

Det bör beaktas att det absoluta minimumet är 3-4 varps/wayfronts som snurrar samtidigt på varje processor. Samtidigt, glöm inte hårdvarubegränsningarna!

Att ha alla dessa detaljer i huvudet blir snabbt tråkigt, så för att beräkna gpu-beläggning erbjöd NVidia ett oväntat verktyg - en Excel(!)-kalkylator full av makron. Där kan du ange information om det maximala antalet trådar för SM, antalet register och storleken på det totala (delade) minnet som är tillgängligt på strömprocessorn, och de funktionsstartparametrar som används - och den visar effektiviteten av resursanvändningen som en procentsats (och du sliter ditt hår och inser att du saknar register för att kunna använda alla kärnor).

Användningsinformation:
http://docs.nvidia.com/cuda/cuda-c-best-practices-guide/#calculating-occupancy

GPU och minnesoperationer

Videokort är optimerade för 128-bitars minnesoperationer. De där. helst bör varje minnesmanipulation helst ändra 4 fyra-byte-värden åt gången. Det största problemet för en programmerare är att moderna GPU-kompilatorer inte vet hur man optimerar sådana saker. Detta måste göras direkt i funktionskoden och ger i genomsnitt en bråkdel av en procentuell ökning av prestanda. Frekvensen av minnesförfrågningar har en mycket större inverkan på prestandan.

Problemet är detta: varje begäran returnerar en bit data som är en multipel av 128 bitar i storlek. Och varje tråd använder bara en fjärdedel av det (i fallet med en vanlig fyra-byte variabel). När intilliggande trådar samtidigt arbetar med data som finns sekventiellt i minnesceller, minskar detta det totala antalet minnesåtkomster. Detta fenomen kallas kombinerade läs- och skrivoperationer ( sammansmält tillträde – bra! både läsa och skriva) – och med korrekt organisation av koden ( stegrad tillgång till sammanhängande minnesbit – dåligt!) kan förbättra prestandan avsevärt. När du organiserar din kärna - kom ihåg - kontinuerlig åtkomst - inom elementen i en minnesrad, är det inte längre så effektivt att arbeta med kolumnelement. Vill du ha mer information? Jag gillade denna pdf - eller googla efter " minnessammansättningstekniker “.

Den ledande positionen i kategorin "flaskhals" upptas av en annan minnesoperation - kopiera data från värdminnet till GPU . Kopiering sker inte hur som helst, utan från ett minnesområde som är speciellt tilldelat av föraren och systemet: när det finns en begäran om att kopiera data, kopierar systemet först dessa data dit och laddar upp dem först till GPU:n. Datatransporthastigheten begränsas av bussens bandbredd PCI Express xN (där N är antalet datalinjer) genom vilka moderna grafikkort kommunicerar med värden.

Men onödig kopiering av långsamt minne på värden är ibland en omotiverad kostnad. Lösningen är att använda den sk fastnat minne – ett speciellt markerat minnesområde, så att operativsystemet inte kan utföra några operationer med det (till exempel dumpa det i swap/flytta efter eget gottfinnande, etc.). Dataöverföring från värden till grafikkortet utförs utan deltagande operativ system- asynkront, via DMA (direkt minnesåtkomst).

Och till sist, lite mer om minnet. Delat minne på en multiprocessor är vanligtvis organiserat i form av minnesbanker som innehåller 32-bitars ord - data. Antalet banker, enligt god tradition, varierar från en GPU-generation till en annan - 16/32 Om varje tråd kommer åt en separat bank för data är allt bra. Annars får vi flera läs/skrivförfrågningar till en bank och vi får en konflikt ( konflikt med delad minnesbank). Sådana motstridiga samtal serialiseras och exekveras därför sekventiellt snarare än parallellt. Om alla trådar kommer åt en bank används ett "broadcast"-svar ( utsända) och det finns ingen konflikt. Det finns flera sätt att effektivt hantera åtkomstkonflikter, jag gillade det beskrivning av de viktigaste teknikerna för att bli av med åtkomstkonflikter till minnesbanker – .

Hur gör man matteoperationer ännu snabbare? Kom ihåg det:

  • Dubbla precisionsberäkningar är en hög belastningsoperation med fp64 >> fp32
  • konstanter av formen 3.13 i koden tolkas som standard som fp64 om 3.14f inte är explicit specificerat
  • För att optimera matematiken skulle det vara en bra idé att kontrollera guiderna för att se om kompilatorn har några flaggor
  • Tillverkare inkluderar funktioner i sina SDK:er som utnyttjar enhetsfunktioner för att uppnå prestanda (ofta på bekostnad av portabilitet)

Det är vettigt för CUDA-utvecklare att ägna stor uppmärksamhet åt konceptet cuda ström låter dig köra flera kärnfunktioner på en enhet samtidigt eller kombinera asynkron kopiering av data från värden till enheten medan du kör funktioner. OpenCL tillhandahåller ännu inte sådan funktionalitet :)

Skrot för profilering:

NVifia Visual Profiler är ett intressant verktyg som analyserar både CUDA- och OpenCL-kärnor.

P.S. Som en mer omfattande guide till optimering kan jag rekommendera att googla alla typer av guide för bästa praxis för OpenCL och CUDA.

  • ,