Activați accelerarea GPU. Optimizare GPU - truismes Utilizarea GPU

Una dintre cele mai ascunse caracteristici din recenta actualizare Windows 10 este capacitatea de a verifica ce aplicații folosesc unitatea de procesare grafică (GPU). Dacă ați deschis vreodată Task Manager, probabil că v-ați uitat la utilizarea procesorului pentru a vedea care aplicații folosesc cel mai mult procesor. Ultimele actualizări au adăugat o caracteristică similară, dar pentru procesoarele grafice GPU. Acest lucru vă ajută să înțelegeți cât de intense sunt software-ul și jocurile dvs. pe GPU fără a fi nevoie să descărcați software terță parte. Există o altă caracteristică interesantă care vă ajută să vă descărcați procesorul pe GPU. Recomand să citești cum să alegi.

De ce nu am GPU în managerul de activități?

Din păcate, nu toate plăcile video vor putea oferi sistemului Windows statisticile necesare pentru a citi GPU-ul. Pentru a fi sigur, puteți utiliza rapid instrumentul de diagnosticare DirectX pentru a verifica această tehnologie.

  1. Faceți clic pe " start" și scrieți în căutare dxdiag pentru a rula Instrumentul de diagnosticare DirectX.
  2. Accesați „fila” Ecran", din dreapta in coloana " şoferii„trebuie să ai Model WDDM mai mult decât versiunea 2.0 pentru utilizarea graficelor GPU în managerul de activități.

Activați graficul GPU în managerul de activități

Pentru a vedea utilizarea GPU-ului pentru fiecare aplicație, trebuie să deschideți managerul de activități.

  • Apăsați o combinație de butoane Ctrl + Shift + Esc pentru a deschide managerul de activități.
  • Faceți clic dreapta în managerul de activități pe caseta „gol”. Nume"și verificați din meniul drop-down GPU De asemenea, puteți observa Miez GPU pentru a vedea ce programe îl folosesc.
  • Acum, în managerul de activități, graficul GPU și nucleul GPU sunt vizibile în partea dreaptă.


Vedeți performanța generală a GPU-ului

Puteți monitoriza utilizarea generală a GPU-ului pentru a o monitoriza sub sarcini grele și pentru a o analiza. În acest caz, puteți vedea tot ce aveți nevoie în fila „ Performanţă" prin selectare procesor grafic.


Fiecare element GPU este defalcat în grafice individuale pentru a vă oferi și mai multe informații despre modul în care este utilizat GPU-ul dvs. Dacă doriți să modificați graficele afișate, puteți face clic pe săgeata mică de lângă numele fiecărei sarcini. Acest ecran arată, de asemenea, versiunea și data driverului dvs., care este o alternativă bună la utilizarea DXDiag sau Device Manager.


Odată am avut ocazia să vorbesc la piața de calculatoare cu directorul tehnic al uneia dintre numeroasele companii care vând laptopuri. Acest „specialist” a încercat să explice, spumegând la gură, exact ce configurație de laptop aveam nevoie. Mesajul principal al monologului său a fost că timpul unităților centrale de procesare (CPU) a trecut, iar acum toate aplicațiile folosesc în mod activ calculele pe procesorul grafic (GPU) și, prin urmare, performanța unui laptop depinde în întregime de GPU și tu nu trebuie să acordați atenție CPU-ului. Dându-mi seama că a mă certa și a încerca să raționez cu acest director tehnic era absolut inutilă, nu am pierdut timpul și am cumpărat laptopul de care aveam nevoie într-un alt pavilion. Cu toate acestea, însuși faptul unei asemenea incompetențe flagrante a vânzătorului m-a lovit. Ar fi de înțeles dacă ar încerca să mă înșele ca cumpărător. Deloc. A crezut sincer în ceea ce a spus. Da, aparent, marketerii de la NVIDIA și AMD își mănâncă pâinea dintr-un motiv și au reușit să insufle unor utilizatori ideea rolului dominant al procesorului grafic într-un computer modern.

Faptul că calcularea unității de procesare grafică (GPU) devine din ce în ce mai populară astăzi este fără îndoială. Cu toate acestea, acest lucru nu diminuează deloc rolul procesorului central. Mai mult, dacă vorbim despre marea majoritate a aplicațiilor utilizator, astăzi performanța acestora depinde în întregime de performanța procesorului. Adică, marea majoritate a aplicațiilor utilizatorilor nu folosesc GPU computing.

În general, calculul GPU este realizat în principal pe sisteme HPC specializate pentru calcul științific. Dar aplicațiile de utilizator care folosesc GPU computing pot fi numărate pe o mână. Trebuie remarcat imediat că termenul „GPU computing” în acest caz nu este în întregime corect și poate induce în eroare. Cert este că, dacă o aplicație folosește GPU computing, asta nu înseamnă că procesorul central este inactiv. Calculul GPU nu implică transferul sarcinii de la procesorul central la procesorul grafic. De regulă, procesorul central rămâne ocupat, iar utilizarea unui procesor grafic, împreună cu procesorul central, poate îmbunătăți performanța, adică reduce timpul necesar pentru a finaliza o sarcină. Mai mult decât atât, GPU-ul în sine acționează aici ca un fel de coprocesor pentru CPU, dar în niciun caz nu îl înlocuiește complet.

Pentru a înțelege de ce GPU computing nu este un panaceu și de ce este incorect să spunem că capabilitățile sale de calcul sunt superioare celor ale procesorului, este necesar să înțelegem diferența dintre un procesor central și un procesor grafic.

Diferențele dintre arhitecturile GPU și CPU

Miezurile CPU sunt proiectate pentru a executa un singur flux de instrucțiuni secvențiale la performanță maximă, în timp ce nucleele GPU sunt proiectate pentru a executa rapid un număr foarte mare de fluxuri de instrucțiuni paralele. Aceasta este diferența fundamentală dintre GPU-uri și procesoarele centrale. CPU este un procesor de uz general sau de uz general optimizat pentru performanță ridicată dintr-un singur flux de instrucțiuni care gestionează atât numere întregi, cât și numere în virgulă mobilă. În acest caz, accesul la memorie cu date și instrucțiuni are loc predominant aleatoriu.

Pentru a îmbunătăți performanța procesorului, acestea sunt proiectate să execute cât mai multe instrucțiuni în paralel. De exemplu, în acest scop, nucleele procesorului folosesc o unitate de execuție a instrucțiunilor în afara ordinului, care vă permite să reordonați instrucțiunile din ordinea în care au fost primite, ceea ce vă permite să creșteți nivelul de paralelism în implementarea instrucțiunilor la nivelul unui fir. Cu toate acestea, acest lucru încă nu permite executarea în paralel a unui număr mare de instrucțiuni, iar suprasarcina de paralelizare a instrucțiunilor din nucleul procesorului se dovedește a fi foarte semnificativă. Acesta este motivul pentru care procesoarele de uz general nu au un număr foarte mare de unități de execuție.

Procesorul grafic este proiectat fundamental diferit. A fost conceput inițial pentru a rula un număr mare de fluxuri de comandă paralele. În plus, aceste fluxuri de comandă sunt paralelizate de la început și pur și simplu nu există costuri generale pentru paralelizarea instrucțiunilor în GPU. GPU-ul este proiectat pentru a reda imagini. Pentru a spune simplu, este nevoie de un grup de poligoane ca intrare, efectuează toate operațiunile necesare și produce pixeli ca ieșire. Procesarea poligoanelor și a pixelilor este independentă; aceștia pot fi procesați în paralel, separat unul de celălalt. Prin urmare, datorită organizării inerente paralele a muncii, GPU utilizează un număr mare de unități de execuție, care sunt ușor de încărcat, spre deosebire de fluxul secvențial de instrucțiuni pentru CPU.

Grafica și procesoarele centrale diferă, de asemenea, în principiile accesului la memorie. Într-un GPU, accesul la memorie este ușor de previzibil: dacă un texel de textură este citit din memorie, atunci după ceva timp va veni termenul limită pentru texelii vecini. La înregistrare, se întâmplă același lucru: dacă un pixel este scris în framebuffer, atunci după câteva cicluri de ceas pixelul situat lângă acesta va fi scris. Prin urmare, GPU-ul, spre deosebire de CPU, pur și simplu nu are nevoie de o memorie cache mare, iar texturile necesită doar câțiva kiloocteți. Principiul lucrului cu memorie este diferit și pentru GPU-uri și procesoare. Deci, toate GPU-urile moderne au mai multe controlere de memorie, iar memoria grafică în sine este mai rapidă, astfel încât GPU-urile au mult mai multe O lățime de bandă a memoriei mai mare în comparație cu procesoarele universale, ceea ce este, de asemenea, foarte important pentru calculele paralele care operează cu fluxuri de date uriașe.

În procesoarele universale O Cea mai mare parte a zonei de cip este ocupată de diverse buffere de comandă și date, unități de decodare, unități de predicție a ramurilor hardware, unități de reordonare a instrucțiunilor și memorie cache de primul, al doilea și al treilea nivel. Toate aceste unități hardware sunt necesare pentru a accelera execuția câtorva fire de comandă, paralelizându-le la nivelul nucleului procesorului.

Unitățile de execuție în sine ocupă relativ puțin spațiu într-un procesor universal.

Într-un procesor grafic, dimpotrivă, zona principală este ocupată de numeroase unități de execuție, ceea ce îi permite să proceseze simultan câteva mii de fire de comandă.

Putem spune că, spre deosebire de procesoarele moderne, GPU-urile sunt proiectate pentru calcule paralele cu un număr mare de operații aritmetice.

Este posibil să se utilizeze puterea de calcul a GPU-urilor pentru sarcini non-grafice, dar numai dacă problema rezolvată permite posibilitatea paralelizării algoritmilor în sute de unități de execuție disponibile în GPU. În special, calculele GPU arată rezultate excelente atunci când aceeași secvență de operații matematice este aplicată unui volum mare de date. În acest caz, cele mai bune rezultate sunt obținute dacă raportul dintre numărul de instrucțiuni aritmetice și numărul de accesări la memorie este suficient de mare. Această operațiune solicită mai puțin controlul execuției și nu necesită utilizarea unei memorie cache mari.

Există multe exemple de calcule științifice în care avantajul GPU-ului față de CPU în ceea ce privește eficiența computațională este incontestabil. Astfel, multe aplicații științifice în modelarea moleculară, dinamica gazelor, dinamica fluidelor și altele sunt perfect potrivite pentru calcule pe GPU.

Deci, dacă algoritmul pentru rezolvarea unei probleme poate fi paralelizat în mii de fire individuale, atunci eficiența rezolvării unei astfel de probleme folosind un GPU poate fi mai mare decât rezolvarea acesteia folosind doar un procesor de uz general. Cu toate acestea, nu puteți transfera atât de ușor soluția unei probleme de la CPU la GPU, fie și doar pentru că CPU și GPU folosesc comenzi diferite. Adică, atunci când un program este scris pentru o soluție pe un CPU, se folosește setul de comenzi x86 (sau un set de comenzi compatibil cu o arhitectură specifică a procesorului), dar pentru GPU se folosesc seturi de comenzi complet diferite, care din nou iau în considerare luați în considerare arhitectura și capacitățile sale. Când se dezvoltă jocuri 3D moderne, sunt folosite API-urile DirectX și OpenGL, permițând programatorilor să lucreze cu shadere și texturi. Cu toate acestea, utilizarea API-urilor DirectX și OpenGL pentru calcule non-grafice pe GPU nu este cea mai bună opțiune.

NVIDIA CUDA și AMD APP

De aceea, când au început primele încercări de implementare a calculului non-grafic pe GPU (General Purpose GPU, GPGPU), a apărut compilatorul BrookGPU. Înainte de crearea sa, dezvoltatorii trebuiau să acceseze resursele plăcii video prin intermediul API-ului grafic OpenGL sau Direct3D, ceea ce a complicat semnificativ procesul de programare, deoarece necesita cunoștințe specifice - trebuiau să învețe principiile lucrului cu obiecte 3D (shadere, texturi etc.). ). Acesta a fost motivul pentru utilizarea foarte limitată a GPGPU în produsele software. BrookGPU a devenit un fel de „traducător”. Aceste extensii de streaming pentru limbajul C au ascuns API-ul 3D de programatori, iar atunci când îl foloseau, nevoia de cunoaștere a programării 3D practic a dispărut. Puterea de calcul a plăcilor video a devenit disponibilă programatorilor sub forma unui coprocesor suplimentar pentru calcule paralele. Compilatorul BrookGPU a procesat fișierul cu cod C și extensii, cod de construcție legat de o bibliotecă cu suport DirectX sau OpenGL.

Mulțumită în mare parte BrookGPU, NVIDIA și ATI (acum AMD) au remarcat tehnologia emergentă de calcul de uz general pe GPU și au început să-și dezvolte propriile implementări care oferă acces direct și mai transparent la unitățile de calcul ale acceleratoarelor 3D.

Drept urmare, NVIDIA a dezvoltat o arhitectură hardware și software pentru calculul paralel, CUDA (Compute Unified Device Architecture). Arhitectura CUDA permite calculul non-grafic pe GPU-urile NVIDIA.

Lansarea versiunii publice beta a SDK-ului CUDA a avut loc în februarie 2007. CUDA API se bazează pe un dialect simplificat al limbajului C. Arhitectura CUDA SDK permite programatorilor să implementeze algoritmi care rulează pe GPU-uri NVIDIA și includ funcții speciale în textul programului C. Pentru a traduce cu succes codul în această limbă, SDK-ul CUDA include propriul compilator de linie de comandă NVIDIA nvcc.

CUDA este un software multiplatform pentru sisteme de operare precum Linux, Mac OS X și Windows.

AMD (ATI) a dezvoltat, de asemenea, propria sa versiune a tehnologiei GPGPU, care se numea anterior ATI Stream, iar acum AMD Accelerated Parallel Processing (APP). Aplicația AMD se bazează pe standardul industrial deschis OpenCL (Open Computing Language). Standardul OpenCL oferă paralelism la nivel de instrucțiune și la nivel de date și este o implementare a tehnicii GPGPU. Este un standard complet deschis și este gratuit pentru utilizare. Rețineți că AMD APP și NVIDIA CUDA sunt incompatibile între ele, totuși, cea mai recentă versiune de NVIDIA CUDA acceptă și OpenCL.

Testarea GPGPU în convertoare video

Așadar, am aflat că tehnologia CUDA este folosită pentru a implementa GPGPU pe GPU-urile NVIDIA, iar API-ul APP este folosit pe GPU-urile AMD. După cum s-a menționat deja, utilizarea calculului non-grafic pe GPU este recomandabilă numai dacă problema rezolvată poate fi paralelizată în mai multe fire. Cu toate acestea, majoritatea aplicațiilor utilizator nu îndeplinesc acest criteriu. Cu toate acestea, există câteva excepții. De exemplu, majoritatea convertoarelor video moderne acceptă capacitatea de a utiliza calcularea pe GPU-uri NVIDIA și AMD.

Pentru a afla cât de eficient este utilizat calculul GPU în convertoarele video personalizate, am selectat trei soluții populare: Xilisoft Video Converter Ultimate 7.7.2, Wondershare Video Converter Ultimate 6.0.3.2 și Movavi Video Converter 10.2.1. Aceste convertoare acceptă capacitatea de a utiliza GPU-uri NVIDIA și AMD și puteți dezactiva această caracteristică în setările convertorului video, ceea ce vă permite să evaluați eficiența utilizării GPU-ului.

Pentru conversia video, am folosit trei videoclipuri diferite.

Primul videoclip a durat 3 minute și 35 de secunde și o dimensiune de 1,05 GB. A fost înregistrat în formatul de stocare a datelor mkv (container) și avea următoarele caracteristici:

  • video:
    • format - MPEG4 Video (H264),
    • rezoluție - 1920*um*1080,
    • modul bitrate - Variabil,
    • rata medie de biți video - 42,1 Mbit/s,
    • rata maximă de biți video - 59,1 Mbit/s,
    • frame rate - 25 fps;
  • audio:
    • format - MPEG-1 Audio,
    • bitrate audio - 128 Kbps,
    • numărul de canale - 2,

Al doilea videoclip a durat 4 minute și 25 de secunde și o dimensiune de 1,98 GB. A fost înregistrată în formatul de stocare a datelor MPG (container) și avea următoarele caracteristici:

  • video:
    • format - MPEG-PS (MPEG2 Video),
    • rezoluție - 1920*um*1080,
    • Bitrate mode - Variabil.
    • rata medie de biți video - 62,5 Mbit/s,
    • rata maximă de biți video - 100 Mbit/s,
    • frame rate - 25 fps;
  • audio:
    • format - MPEG-1 Audio,
    • bitrate audio - 384 Kbps,
    • numărul de canale - 2,

Al treilea videoclip a avut o durată de 3 minute și 47 de secunde și o dimensiune de 197 MB. A fost scris în formatul de stocare a datelor MOV (container) și avea următoarele caracteristici:

  • video:
    • format - MPEG4 Video (H264),
    • rezoluție - 1920*um*1080,
    • modul bitrate - Variabil,
    • Rata de biți video - 7024 Kbps,
    • frame rate - 25 fps;
  • audio:
    • format - AAC,
    • bitrate audio - 256 Kbps,
    • numărul de canale - 2,
    • frecvența de eșantionare - 48 kHz.

Toate cele trei videoclipuri de testare au fost convertite folosind convertoare video în formatul de stocare a datelor MP4 (codec H.264) pentru vizionare pe tableta iPad 2. Rezoluția fișierului video de ieșire a fost de 1280*um*720.

Vă rugăm să rețineți că nu am folosit exact aceleași setări de conversie în toate cele trei convertoare. De aceea, este incorect să comparăm eficiența convertoarelor video înșiși pe baza timpului de conversie. Astfel, în convertorul video Xilisoft Video Converter Ultimate 7.7.2, pentru conversie a fost folosit presetarea iPad 2 - H.264 HD Video. Această presetare folosește următoarele setări de codificare:

  • codec - MPEG4 (H.264);
  • rezoluție - 1280*um*720;
  • frame rate - 29,97 fps;
  • bitrate video - 5210 Kbps;
  • codec audio - AAC;
  • bitrate audio - 128 Kbps;
  • numărul de canale - 2;
  • frecvența de eșantionare - 48 kHz.

Wondershare Video Converter Ultimate 6.0.3.2 a folosit presetarea iPad 2 cu următoarele setări suplimentare:

  • codec - MPEG4 (H.264);
  • rezoluție - 1280*um*720;
  • frame rate - 30 fps;
  • bitrate video - 5000 Kbps;
  • codec audio - AAC;
  • bitrate audio - 128 Kbps;
  • numărul de canale - 2;
  • frecvența de eșantionare - 48 kHz.

Movavi Video Converter 10.2.1 a folosit presetarea iPad (1280*um*720, H.264) (*.mp4) cu următoarele setări suplimentare:

  • format video - H.264;
  • rezoluție - 1280*um*720;
  • frame rate - 30 fps;
  • bitrate video - 2500 Kbps;
  • codec audio - AAC;
  • bitrate audio - 128 Kbps;
  • numărul de canale - 2;
  • frecvența de eșantionare - 44,1 kHz.

Fiecare video sursă a fost convertit de cinci ori pe fiecare dintre convertoare video, folosind atât GPU, cât și numai CPU. După fiecare conversie, computerul a repornit.

Ca rezultat, fiecare videoclip a fost convertit de zece ori în fiecare convertor video. Pentru a automatiza această muncă de rutină, a fost scris un utilitar special cu o interfață grafică, care vă permite să automatizați complet procesul de testare.

Configurarea standului de testare

Standul de testare a avut următoarea configurație:

  • procesor - Intel Core i7-3770K;
  • placa de baza - Gigabyte GA-Z77X-UD5H;
  • chipset placa de baza - Intel Z77 Express;
  • memorie - DDR3-1600;
  • capacitate memorie - 8 GB (două module GEIL a câte 4 GB fiecare);
  • modul de funcționare a memoriei - dual-channel;
  • placa video - NVIDIA GeForce GTX 660Ti (driver video 314.07);
  • unitate - Intel SSD 520 (240 GB).

La stand a fost instalat sistemul de operare Windows 7 Ultimate (64 de biți).

Inițial, am testat procesorul și toate celelalte componente ale sistemului în modul normal. În același timp, procesorul Intel Core i7-3770K a funcționat la o frecvență standard de 3,5 GHz cu modul Turbo Boost activat (frecvența maximă a procesorului în modul Turbo Boost este de 3,9 GHz).

Am repetat apoi procesul de testare, dar cu procesorul overclockat la o frecvență fixă ​​de 4,5 GHz (fără a folosi modul Turbo Boost). Acest lucru a făcut posibilă identificarea dependenței vitezei de conversie de frecvența procesorului (CPU).

La următoarea etapă de testare, am revenit la setările standard ale procesorului și am testat repetat cu alte plăci video:

  • NVIDIA GeForce GTX 280 (driver 314.07);
  • NVIDIA GeForce GTX 460 (driver 314.07);
  • AMD Radeon HD6850 (driver 13.1).

Astfel, conversia video a fost realizată pe patru plăci video de arhitecturi diferite.

Placa video senior NVIDIA GeForce 660Ti se bazează pe un procesor grafic cu același nume, codificat GK104 (arhitectura Kepler), produs folosind o tehnologie de proces de 28 nm. Acest GPU conține 3,54 miliarde de tranzistori și are o zonă a matriței de 294 mm2.

Reamintim că procesorul grafic GK104 include patru clustere de procesare grafică (Graphics Processing Clusters, GPC). Clusterele GPC sunt dispozitive independente în cadrul procesorului și sunt capabile să funcționeze ca dispozitive separate, deoarece au toate resursele necesare: rasterizatoare, motoare de geometrie și module de textură.

Fiecare astfel de cluster are două multiprocesoare SMX (Streaming Multiprocessor), dar în procesorul GK104 un multiprocesor este blocat într-unul dintre clustere, deci sunt șapte multiprocesoare SMX în total.

Fiecare multiprocesor de streaming SMX conține 192 de nuclee de calcul de streaming (nuclee CUDA), astfel încât procesorul GK104 are un total de 1344 de nuclee CUDA. În plus, fiecare multiprocesor SMX conține 16 unități de textură (TMU), 32 de unități cu funcții speciale (SFU), 32 de unități de stocare a încărcăturii (LSU), un motor PolyMorph și multe altele.

GeForce GTX 460 se bazează pe un GPU codificat GF104 bazat pe arhitectura Fermi. Acest procesor este fabricat folosind o tehnologie de proces de 40 nm și conține aproximativ 1,95 miliarde de tranzistori.

GPU-ul GF104 include două clustere de procesare grafică GPC. Fiecare dintre ele are patru multiprocesoare de streaming SM, dar în procesorul GF104 dintr-unul dintre clustere un multiprocesor este blocat, deci există doar șapte multiprocesoare SM.

Fiecare multiprocesor de streaming SM conține 48 de nuclee de calcul de streaming (nuclee CUDA), astfel încât procesorul GK104 are un total de 336 de nuclee CUDA. În plus, fiecare multiprocesor SM conține opt unități de textură (TMU), opt unități de funcții speciale (SFU), 16 unități de stocare a încărcăturii (LSU), un motor PolyMorph și multe altele.

GeForce GTX 280 GPU face parte din a doua generație a arhitecturii GPU unificate NVIDIA și este foarte diferită ca arhitectură de Fermi și Kepler.

GPU-ul GeForce GTX 280 constă din clustere de procesare a texturii (TPC), care, deși similare, sunt foarte diferite de clusterele de procesare grafică GPC din arhitecturile Fermi și Kepler. Există un total de zece astfel de clustere în procesorul GeForce GTX 280. Fiecare cluster TPC include trei multiprocesoare de streaming SM și opt unități de eșantionare și filtrare a texturii (TMU). Fiecare multiprocesor este format din opt procesoare de flux (SP). Multiprocesoarele conțin și blocuri pentru eșantionarea și filtrarea datelor de textură, utilizate atât în ​​grafică, cât și în unele sarcini de calcul.

Astfel, într-un cluster TPC există 24 de procesoare de flux, iar în GPU-ul GeForce GTX 280 sunt deja 240 dintre ele.

Caracteristicile rezumate ale plăcilor video de pe GPU-urile NVIDIA utilizate în testare sunt prezentate în tabel.

Tabelul de mai jos nu include placa video AMD Radeon HD6850, ceea ce este destul de natural, deoarece caracteristicile sale tehnice sunt greu de comparat cu plăcile video NVIDIA. Prin urmare, îl vom lua în considerare separat.

GPU-ul AMD Radeon HD6850, cu numele de cod Barts, este fabricat folosind o tehnologie de proces de 40 nm și conține 1,7 miliarde de tranzistori.

Arhitectura procesorului AMD Radeon HD6850 este o arhitectură unificată cu o serie de procesoare comune pentru procesarea în flux a mai multor tipuri de date.

Procesorul AMD Radeon HD6850 este format din 12 nuclee SIMD, fiecare dintre acestea conținând 16 unități de procesor de flux superscalar și patru unități de textură. Fiecare procesor de flux superscalar conține cinci procesoare de flux de uz general. Astfel, în total, GPU-ul AMD Radeon HD6850 are 12*um*16*um*5=960 de procesoare universale de flux.

Frecvența GPU a plăcii video AMD Radeon HD6850 este de 775 MHz, iar frecvența efectivă a memoriei GDDR5 este de 4000 MHz. Capacitatea memoriei este de 1024 MB.

Rezultatele testului

Deci, să ne uităm la rezultatele testelor. Să începem cu primul test, când folosim placa video NVIDIA GeForce GTX 660Ti și modul de operare standard al procesorului Intel Core i7-3770K.

În fig. 1-3 arată rezultatele conversiei a trei videoclipuri de testare folosind trei convertoare în moduri cu și fără GPU.

După cum se poate observa din rezultatele testării, efectul utilizării GPU-ului este evident. Pentru convertorul video Xilisoft Video Converter Ultimate 7.7.2, atunci când utilizați un GPU, timpul de conversie este redus cu 14, 9 și 19% pentru primul, al doilea și, respectiv, al treilea videoclip.

Pentru Wondershare Video Converter Ultimate 6.0.32, utilizarea unui GPU reduce timpul de conversie cu 10%, 13% și 23% pentru primul, al doilea și, respectiv, al treilea videoclip.

Dar convertorul care beneficiază cel mai mult de pe urma utilizării unui procesor grafic este Movavi Video Converter 10.2.1. Pentru primul, al doilea și al treilea videoclip, reducerea timpului de conversie este de 64, 81 și, respectiv, 41%.

Este clar că beneficiul utilizării unui GPU depinde atât de video sursă, cât și de setările de conversie video, ceea ce, de fapt, este ceea ce demonstrează rezultatele noastre.

Acum să vedem care va fi câștigul de timp de conversie atunci când se face overclockarea procesorului Intel Core i7-3770K la 4,5 GHz. Dacă presupunem că în modul normal toate nucleele de procesor sunt încărcate în timpul conversiei, iar în modul Turbo Boost funcționează la o frecvență de 3,7 GHz, atunci creșterea frecvenței la 4,5 GHz corespunde unui overclock de frecvență de 22%.

În fig. 4-6 arată rezultatele conversiei a trei videoclipuri de testare la overclockarea procesorului în moduri folosind un procesor grafic și fără. În acest caz, utilizarea unui procesor grafic permite un câștig în timpul de conversie.

Pentru convertorul video Xilisoft Video Converter Ultimate 7.7.2, atunci când utilizați un GPU, timpul de conversie este redus cu 15, 9 și 20% pentru primul, al doilea și, respectiv, al treilea videoclip.

Pentru Wondershare Video Converter Ultimate 6.0.32, utilizarea unui GPU poate reduce timpul de conversie cu 10, 10 și 20% pentru primul, al doilea și, respectiv, al treilea videoclip.

Pentru Movavi Video Converter 10.2.1, utilizarea unui procesor grafic poate reduce timpul de conversie cu 59, 81 și, respectiv, 40%.

Desigur, este interesant de văzut cum overclockarea CPU poate reduce timpii de conversie cu și fără un GPU.

În fig. Figurile 7-9 arată rezultatele comparării timpului de conversie a videoclipurilor fără a utiliza un procesor grafic în modul de funcționare normal al procesorului și în modul overclock. Deoarece în acest caz conversia este efectuată numai de procesor fără calcule pe GPU, este evident că creșterea frecvenței de ceas a procesorului duce la o reducere a timpului de conversie (creșterea vitezei de conversie). Este la fel de evident că reducerea vitezei de conversie ar trebui să fie aproximativ aceeași pentru toate videoclipurile de testare. Astfel, pentru convertorul video Xilisoft Video Converter Ultimate 7.7.2, la overclockarea procesorului, timpul de conversie este redus cu 9, 11 și 9% pentru primul, al doilea și, respectiv, al treilea videoclip. Pentru Wondershare Video Converter Ultimate 6.0.32, timpul de conversie este redus cu 9, 9 și 10% pentru primul, al doilea și, respectiv, al treilea videoclip. Ei bine, pentru convertorul video Movavi Video Converter 10.2.1, timpul de conversie este redus cu 13, 12 și, respectiv, 12%.

Astfel, la overclockarea frecvenței procesorului cu 20%, timpul de conversie se reduce cu aproximativ 10%.

Să comparăm timpul pentru conversia videoclipurilor folosind un procesor grafic în modul procesor normal și în modul overclocking (Fig. 10-12).

Pentru convertorul video Xilisoft Video Converter Ultimate 7.7.2, la overclockarea procesorului, timpul de conversie este redus cu 10, 10 și 9% pentru primul, al doilea și, respectiv, al treilea videoclip. Pentru Wondershare Video Converter Ultimate 6.0.32, timpul de conversie este redus cu 9, 6 și 5% pentru primul, al doilea și, respectiv, al treilea videoclip. Ei bine, pentru convertorul video Movavi Video Converter 10.2.1, timpul de conversie este redus cu 0,2, 10 și, respectiv, 10%.

După cum puteți vedea, pentru convertoarele Xilisoft Video Converter Ultimate 7.7.2 și Wondershare Video Converter Ultimate 6.0.32, reducerea timpului de conversie la overclockarea procesorului este aproximativ aceeași atât la utilizarea unui procesor grafic, cât și fără a-l folosi, ceea ce este logic, deoarece aceste convertoare nu folosesc foarte eficient calcularea GPU. Dar pentru Movavi Video Converter 10.2.1, care utilizează eficient calculul GPU, overclockarea procesorului în modul de calcul GPU are un efect redus asupra reducerii timpului de conversie, ceea ce este de asemenea de înțeles, deoarece în acest caz sarcina principală cade pe procesorul grafic .

Acum să ne uităm la rezultatele testelor cu diferite plăci video.

S-ar părea că, cu cât placa video este mai puternică și cu cât mai multe nuclee CUDA (sau procesoare de flux universal pentru plăcile video AMD) în procesorul grafic, cu atât conversia video ar trebui să fie mai eficientă atunci când se folosește un procesor grafic. Dar, în practică, nu funcționează chiar așa.

În ceea ce privește plăcile video bazate pe GPU-uri NVIDIA, situația este următoarea. Când utilizați convertoare Xilisoft Video Converter Ultimate 7.7.2 și Wondershare Video Converter Ultimate 6.0.32, timpul de conversie practic nu depinde în niciun fel de tipul de placă video folosită. Adică, pentru plăcile video NVIDIA GeForce GTX 660Ti, NVIDIA GeForce GTX 460 și NVIDIA GeForce GTX 280 în modul de calcul GPU, timpul de conversie este același (Fig. 13-15).

Orez. 1. Rezultatele conversiei primului
test video în modul normal
funcţionarea procesorului

procesor pe plăcile video în modul GPU

Orez. 14. Rezultatele comparației timpului de conversie al celui de-al doilea videoclip

Orez. 15. Rezultatele comparației timpului de conversie al celui de-al treilea videoclip
pe diferite plăci video în modul GPU

Acest lucru poate fi explicat doar prin faptul că algoritmul de calcul GPU implementat în convertoarele Xilisoft Video Converter Ultimate 7.7.2 și Wondershare Video Converter Ultimate 6.0.32 este pur și simplu ineficient și nu permite utilizarea activă a tuturor nucleelor ​​grafice. Apropo, tocmai asta explică faptul că pentru aceste convertoare diferența de timp de conversie în modurile de utilizare a GPU-ului și fără a-l folosi este mică.

În Movavi Video Converter 10.2.1 situația este ușor diferită. După cum ne amintim, acest convertor este capabil să utilizeze foarte eficient calculele GPU și, prin urmare, în modul GPU, timpul de conversie depinde de tipul de placă video utilizată.

Dar cu placa video AMD Radeon HD 6850 totul este ca de obicei. Fie driverul plăcii video este „strâmb”, fie algoritmii implementați în convertoare au nevoie de îmbunătățiri serioase, dar atunci când se utilizează calcularea GPU, rezultatele fie nu se îmbunătățesc, fie se înrăutățesc.

Mai precis, situația este următoarea. Pentru Xilisoft Video Converter Ultimate 7.7.2, atunci când utilizați un GPU pentru a converti primul videoclip de testare, timpul de conversie crește cu 43%, iar la conversia celui de-al doilea videoclip, cu 66%.

Mai mult, Xilisoft Video Converter Ultimate 7.7.2 se caracterizează și prin rezultate instabile. Variația timpului de conversie poate ajunge la 40%! De aceea am repetat toate testele de zece ori și am calculat rezultatul mediu.

Dar pentru Wondershare Video Converter Ultimate 6.0.32 și Movavi Video Converter 10.2.1, atunci când utilizați un GPU pentru a converti toate cele trei videoclipuri, timpul de conversie nu se schimbă deloc! Este probabil ca Wondershare Video Converter Ultimate 6.0.32 și Movavi Video Converter 10.2.1 fie să nu folosească tehnologia AMD APP la conversie, fie ca driverul video AMD să fie pur și simplu „strâmb”, drept urmare tehnologia AMD APP nu funcționează .

concluzii

Pe baza testării, se pot trage următoarele concluzii importante. Convertoarele video moderne pot folosi de fapt tehnologia de calcul GPU, care permite o viteză de conversie crescută. Cu toate acestea, acest lucru nu înseamnă că toate calculele sunt transferate în întregime pe GPU și CPU-ul rămâne neutilizat. După cum arată testele, atunci când se utilizează tehnologia GPGPU, procesorul central rămâne ocupat, ceea ce înseamnă că utilizarea procesoarelor centrale puternice, multi-core în sistemele utilizate pentru conversia video rămâne relevantă. Excepția de la această regulă este tehnologia AMD APP pe GPU-urile AMD. De exemplu, atunci când utilizați Xilisoft Video Converter Ultimate 7.7.2 cu tehnologia AMD APP activată, sarcina CPU este într-adevăr redusă, dar acest lucru duce la faptul că timpul de conversie nu este redus, ci, dimpotrivă, crește.

În general, dacă vorbim despre conversia video cu utilizarea suplimentară a unui procesor grafic, atunci pentru a rezolva această problemă este recomandabil să folosiți plăci video cu GPU-uri NVIDIA. După cum arată practica, numai în acest caz puteți obține o creștere a vitezei de conversie. Mai mult, trebuie să rețineți că creșterea reală a vitezei de conversie depinde de mulți factori. Acestea sunt formatele video de intrare și ieșire și, desigur, convertorul video în sine. Convertoarele Xilisoft Video Converter Ultimate 7.7.2 și Wondershare Video Converter Ultimate 6.0.32 nu sunt potrivite pentru această sarcină, dar convertorul și Movavi Video Converter 10.2.1 sunt capabili să utilizeze foarte eficient capacitățile GPU-ului NVIDIA.

În ceea ce privește plăcile video de pe GPU-urile AMD, acestea nu ar trebui să fie folosite deloc pentru sarcini de conversie video. În cel mai bun caz, acest lucru nu va crește viteza de conversie și, în cel mai rău caz, puteți obține o scădere a acesteia.

Ce program este necesar pentru a extrage criptomonede? Ce trebuie să țineți cont atunci când alegeți echipament minier? Cum să mine Bitcoin și Ethereum folosind o placă video pe un computer?

Se pare că plăcile video puternice sunt necesare nu numai pentru fanii jocurilor spectaculoase pe calculator. Mii de utilizatori din întreaga lume folosesc adaptoare grafice pentru a câștiga criptomonede! De la mai multe carduri cu procesoare puternice mineri crea ferme– centre de calcul care extrag bani digitali practic din aer!

Vă este alături Denis Kuderin, expert al revistei HeatherBober pe probleme de finanțe și multiplicarea lor competentă. Îți voi spune despre ce este minerit pe o placă videoîn 17-18, cum să alegi dispozitivul potrivit pentru a câștiga criptomonede și de ce extragerea de bitcoini pe plăcile video nu mai este profitabilă.

Vei afla si tu de unde să cumpărați cea mai productivă și mai puternică placă video pentru minerit profesional și obțineți sfaturi de specialitate cu privire la îmbunătățirea eficienței instalației dvs. de minerit.

1. Mining pe o placa video - bani usor sau cheltuieli nejustificate

O placă video bună nu este doar un adaptor pentru semnale digitale, ci și un procesor puternic capabil să rezolve cele mai complexe probleme de calcul. Și inclusiv - calculați un cod hash pentru un lanț de blocuri (blockchain). Acest lucru face plăcile grafice instrumentul ideal pentru minerit– minerit de criptomonede.

Întrebare: De ce un procesor de placă video? La urma urmei, fiecare computer are un procesor central? Nu este logic să faci calcule folosindu-l?

Răspuns: Procesorul CPU poate calcula și blocuri, dar o face de sute de ori mai lent decât un procesor de plăci video (GPU). Și nu pentru că unul este mai bun, celălalt este mai rău. Au doar principii de funcționare diferite. Și dacă combinați mai multe plăci video, puterea unui astfel de centru de calcul va crește de câteva ori mai mult.

Pentru cei care nu au idee cum sunt extrași banii digitali, un mic program educațional. Minerit - principala și uneori singura modalitate de a produce criptomonede.

Din moment ce nimeni nu bate sau imprimă acești bani și nu este o substanță materială, ci un cod digital, cineva trebuie să calculeze acest cod. Asta fac minerii, sau mai bine zis, fac computerele lor.

Pe lângă calculele de cod, minerit îndeplinește câteva sarcini mai importante:

  • suport pentru descentralizarea sistemului: lipsa atașării la servere stă la baza blockchain-ului;
  • confirmarea tranzacției– fără minerit, operațiunile nu vor putea intra într-un nou bloc;
  • formarea de noi blocuri ale sistemului– și introducerea lor într-un singur registru pentru toate computerele.

Aș dori să potolesc imediat ardoarea minerilor începători: procesul de minerit devine din ce în ce mai dificil în fiecare an. De exemplu, utilizarea unei plăci video a fost mult timp neprofitabilă.

Numai amatorii dietici minează acum bile tac folosind GPU, deoarece plăcile video au fost înlocuite cu procesoare specializate ASIC. Aceste cipuri consumă mai puțină energie și sunt mai eficiente din punct de vedere computațional. Toată lumea este bună, dar costă aproximativ un ordin de mărime 130-150 mii de ruble .

Model puternic Antminer S9

Din fericire pentru mineri, Bitcoin nu este singura criptomonedă de pe planetă, ci una dintre sutele. Alți bani digitali - Ethereum, Zcash, Expanse, dogecoins etc. Este încă profitabil să mine cu plăci video. Remunerația este stabilă, iar echipamentul se amortiza în aproximativ 6-12 luni.

Dar există o altă problemă - lipsa plăcilor video puternice.. Expresia din jurul criptomonedei a dus la o creștere a prețului acestor dispozitive. Cumpărarea unei plăci video nouă potrivită pentru minerit în Rusia nu este atât de ușoară.

Minerii începători trebuie să comande adaptoare video din magazinele online (inclusiv cele străine) sau să cumpere bunuri uzate. Apropo, nu recomand să faceți acest din urmă: echipamentele miniere devin învechite și se uzează într-un ritm fantastic.

Pe Avito vând chiar ferme întregi pentru minerit de criptomonede.

Există multe motive: unii mineri au „jucat deja suficient” să extragă bani digitali și au decis să se angajeze în operațiuni mai profitabile cu criptomonede (în special, tranzacționarea la schimb), alții și-au dat seama că nu au putut concura cu puternicele clustere chineze care operează pe baza centralelor electrice. Alții au trecut de la plăcile video la ASIC.

Cu toate acestea, nișa aduce în continuare ceva profit, iar dacă începi să folosești o placă video chiar acum, vei mai avea timp să te arunci în vagonul trenului care pleacă în viitor.

Un alt lucru este că sunt din ce în ce mai mulți jucători pe acest teren. Mai mult, numărul total de monede digitale nu crește din aceasta. Dimpotrivă, recompensa devine mai mică.

Deci, acum șase ani, recompensa pentru un blockchain al rețelei Bitcoin era egală cu 50 de monede, acum este doar 12,5 BTK. Complexitatea calculelor a crescut de 10 mii de ori. Adevărat, valoarea Bitcoin în sine a crescut de multe ori în acest timp.

2. Cum să minați criptomonede folosind o placă video - instrucțiuni pas cu pas

Există două opțiuni de minerit - solo și ca parte a unui bazin. Este dificil să faci minerit solo - trebuie să ai o cantitate mare de hashrate(unități de putere) astfel încât calculele începute să aibă o probabilitate de finalizare cu succes.

99% din toți minerii lucrează piscine(în engleză pool – pool) – comunități implicate în distribuirea sarcinilor de calcul. Exploatarea în comun elimină factorul aleatoriu și garantează profituri stabile.

Unul dintre cunoscuții mei de mineri a vorbit despre asta: mine de 3 ani, timp în care nu am comunicat cu nimeni care să mine singur.

Astfel de prospectori sunt asemănători minerilor de aur din secolul al XIX-lea. Puteți căuta ani de zile nuggetul dvs. (în cazul nostru, Bitcoin) și tot nu îl găsiți. Adică, blockchain-ul nu va fi niciodată închis, ceea ce înseamnă că nu veți primi nicio recompensă.

„Vânătorii singuratici” au o șansă ceva mai mare pentru eter și alte cripto-monede.

Datorită algoritmului unic de criptare, ETH nu este extras folosind procesoare speciale (nu au fost încă inventate). Pentru aceasta sunt folosite doar plăcile video. Numeroși fermieri ai timpului nostru încă supraviețuiesc în detrimentul Ethereum-ului și al altor monede alternative.

O placă video nu va fi suficientă pentru a crea o fermă cu drepturi depline: 4 bucăți – „salariu vital” pentru un miner mizând pe profituri stabile. La fel de important este un sistem de răcire puternic pentru adaptoarele video. Și nu pierdeți din vedere un astfel de element de cheltuială precum facturile de electricitate.

Instrucțiunile pas cu pas vă vor proteja de greșeli și vor accelera configurarea procesului.

Pasul 1. Selectați o piscină

Cele mai mari pool-uri de criptomonede din lume se află în China, precum și în Islanda și SUA. Formal, aceste comunități nu au afiliere de stat, dar site-urile de piscină în limba rusă sunt o raritate pe internet.

Deoarece cel mai probabil va trebui să minați Ethereum pe o placă video, va trebui să alegeți comunitatea implicată în calcularea acestei monede. Deși Ethereum este un altcoin relativ tânăr, există multe bazine pentru minerit. Mărimea venitului dvs. și stabilitatea acestuia depind în mare măsură de alegerea comunității.

Selectăm un bazin pe baza următoarelor criterii:

  • performanţă;
  • ore de lucru;
  • faima printre minerii de criptomonede;
  • prezența recenziilor pozitive pe forumuri independente;
  • comoditatea de a retrage bani;
  • mărimea comisionului;
  • principiul calculului profitului.

Schimbările apar zilnic pe piața criptomonedelor. Acest lucru se aplică și creșterilor cursului de schimb și apariției unor noi bani digitali - furci bitcoin. Au loc și schimbări globale.

Astfel, recent a devenit cunoscut faptul că eterul în viitorul apropiat va trece la un sistem fundamental diferit de distribuție a profitului. Pe scurt, veniturile din rețeaua Etherium vor fi câștigate de mineri care au „multe ketse”, adică monede, iar minerii începători vor trebui fie să închidă magazinul, fie să treacă la alți bani.

Dar astfel de „lucruri mărunte” nu i-au oprit niciodată pe entuziaști. Mai mult, există un program numit Profitable Pool. Urmărește automat cele mai profitabile altcoins pentru mine în acest moment. Există, de asemenea, un serviciu de căutare pentru bazinele în sine, precum și evaluările acestora în timp real.

Pasul 2. Instalați și configurați programul

După înregistrarea pe site-ul piscinei, trebuie să descărcați un program special pentru mineri - nu calculați manual codul folosind un calculator. Există și suficiente astfel de programe. Pentru Bitcoin, acesta este - 50 miner sau CGMiner, pentru difuzare – Ethminer.

Instalarea necesită îngrijire și anumite abilități. De exemplu, trebuie să știți ce sunt scripturile și să le puteți introduce în linia de comandă a computerului dvs. Recomand să verificați aspectele tehnice cu minerii practicanți, deoarece fiecare program are propriile sale nuanțe de instalare și configurare.

Pasul 3. Înregistrați portofelul

Dacă nu aveți încă un portofel Bitcoin sau un spațiu de stocare Ethereum, trebuie să le înregistrați. Descărcăm portofele de pe site-urile oficiale.

Uneori, piscinele în sine oferă asistență în această problemă, dar nu gratuit.

Pasul 4. Începeți mineritul și monitorizați statisticile

Mai rămâne doar să începeți procesul și să așteptați primele chitanțe. Asigurați-vă că descărcați un program auxiliar care va monitoriza starea componentelor principale ale computerului dvs. - încărcare, supraîncălzire etc.

Pasul 5. Retrageți criptomoneda

Calculatoarele funcționează non-stop și automat, calculând codul. Tot ce trebuie să faci este să te asiguri că cardurile sau alte sisteme nu dau greș. Criptomoneda va intra în portofel cu o viteză direct proporțională cu cantitatea de hashrate.

Cum se transformă moneda digitală în monedă fiat? O întrebare demnă de un articol separat. Pe scurt, cea mai rapidă cale sunt casele de schimb valutar. Aceștia iau un procent pentru serviciile lor, iar sarcina ta este să găsești cea mai profitabilă rată cu comisionul minim. Un serviciu profesional de comparare a schimbătoarelor vă va ajuta să faceți acest lucru.

– cea mai bună resursă de acest fel din RuNet. Această monitorizare compară performanța a peste 300 de case de schimb valutar și găsește cele mai bune cotații pentru perechile valutare care vă interesează. Mai mult, serviciul indică rezervele de criptomonede în casa de marcat. Listele de monitorizare conțin doar servicii de schimb dovedite și de încredere.

3. Ce să cauți atunci când alegi o placă video pentru minerit

Trebuie să alegeți cu înțelepciune o placă video. Primul pe care îl întâlnești sau cel care este deja pe computer îl va și al meu, dar această putere va fi neglijabilă chiar și pentru eteri.

Principalii indicatori sunt următorii: performanță (putere), consum de energie, răcire, perspective de overclocking.

1) Putere

Totul este simplu aici - cu cât performanța procesorului este mai mare, cu atât mai bine pentru calcularea codului hash. Performanța excelentă este asigurată de cardurile cu o capacitate de memorie de peste 2 GB. Și alegeți dispozitive cu o magistrală de 256 de biți. Cele pe 128 de biți nu sunt potrivite în acest scop.

2) Consumul de energie

Puterea este, desigur, grozavă - hashrate mare și toate astea. Dar nu uitați de indicatorii de consum de energie. Unele ferme productive „mănâncă” atât de multă energie electrică încât costurile sunt abia recuperate sau deloc.

3) Răcire

Cel standard este format din 4-16 cărți. Produce o cantitate excesivă de căldură, care este dăunătoare fierului de călcat și nedorită fermierului însuși. Să locuiești și să lucrezi într-un apartament cu o cameră fără aer condiționat va fi, ca să spunem ușor, inconfortabil.

Răcirea procesorului de înaltă calitate este o condiție indispensabilă pentru minerit de succes

Prin urmare, atunci când alegeți două cărți cu aceeași performanță, acordați preferință celei cu indicator de putere termică mai mică (TDP) . Cei mai buni parametri de răcire sunt demonstrați de cardurile Radeon. Aceleași dispozitive funcționează mai mult decât toate celelalte carduri în modul activ fără uzură.

Răcitoarele suplimentare nu numai că vor elimina excesul de căldură din procesoare, dar le vor prelungi și durata de viață.

4) Capacitate de overclocking

Overclocking este o creștere forțată a performanței unei plăci video. Abilitatea de a „overclocka cardul” depinde de doi parametri - Frecvențele GPU și frecvențele memoriei video. Acestea sunt cele pe care le veți face overclock dacă doriți să vă creșteți puterea de calcul.

Ce plăci video ar trebui să iau? Veți avea nevoie de dispozitive de ultimă generație sau cel puțin de acceleratoare grafice care au fost lansate nu mai devreme de 2-3 ani în urmă. Minerii folosesc carduri AMD Radeon, Nvidia, GeForce GTX.

Aruncă o privire la tabelul de rambursare pentru plăcile video (datele sunt actuale de la sfârșitul anului 2017):

4. De unde să cumpărați o placă video pentru minerit – recenzie a TOP 3 magazine

După cum am spus deja, odată cu popularitatea în creștere a mineritului, plăcile video au devenit o marfă limitată. Pentru a cumpăra dispozitivul potrivit, va trebui să cheltuiți mult timp și efort.

Revizuirea noastră a celor mai bune puncte de vânzare online vă va ajuta.

1) TopComputer

Hipermarket din Moscova specializat în calculatoare și electrocasnice. Funcționează pe piață de mai bine de 14 ani, furnizând mărfuri din toată lumea la prețuri aproape de producător. Există un serviciu de livrare promptă, gratuit pentru moscoviți.

La momentul scrierii, există carduri la vânzare AMD, Nvidia(8 Gb) și alte soiuri potrivite pentru minerit.

2) Mybitcoinshop

magazin special, comerțul exclusiv cu mărfuri pentru minerit. Aici veți găsi tot ce aveți nevoie pentru a construi o fermă acasă - plăci video cu configurația necesară, surse de alimentare, adaptoare și chiar mineri ASIC (pentru mineri de nouă generație). Există o livrare plătită și ridicare dintr-un depozit din Moscova.

Compania a primit în mod repetat titlul neoficial de cel mai bun magazin pentru mineri din Federația Rusă. Servirea promptă, atitudinea prietenoasă față de clienți, echipamentele avansate sunt principalele componente ale succesului.

3) Ship Shop America

Achiziționarea și livrarea mărfurilor din SUA. O companie intermediară pentru cei care au nevoie de produse miniere cu adevărat exclusive și de ultimă generație.

Partener direct al producătorului lider de plăci video pentru jocuri și minerit – Nvidia. Perioada maximă de așteptare pentru mărfuri este de 14 zile.

5. Cum să crești veniturile din minerit pe o placă video - 3 sfaturi utile

Cititorii nerăbdători care doresc să înceapă mineritul chiar acum și să primească venituri începând de mâine dimineață cu siguranță vor întreba - cât câștigă minerii?

Câștigurile depind de echipament, rata criptomonedei, eficiența pool-ului, puterea fermei, hashrate și o grămadă de alți factori. Unii reușesc să primească până la lunar 70.000 de ruble , alții sunt mulțumiți 10 dolari in saptamana. Aceasta este o afacere instabilă și imprevizibilă.

Sfaturi utile te vor ajuta să-ți crești veniturile și să-ți optimizezi cheltuielile.

Dacă extrageți o monedă care crește rapid ca preț, veți câștiga mai mult. De exemplu, eterul costă acum aproximativ 300 de dolari, Bitcoin – mai mult 6000 . Dar trebuie să țineți cont nu numai de valoarea actuală, ci și de rata de creștere pe parcursul săptămânii.

Sfat 2. Folosiți un calculator de minerit pentru a alege hardware-ul optim

Un calculator de minerit pe un site web de piscină sau alt serviciu specializat vă va ajuta să alegeți programul optim și chiar o placă video pentru minerit.

Utilizarea GPU Computing cu C++ AMP

Până acum, în discutarea tehnicilor de programare paralelă, am luat în considerare doar nucleele de procesor. Am dobândit unele abilități în paralelizarea programelor pe mai multe procesoare, sincronizarea accesului la resursele partajate și utilizarea primitivelor de sincronizare de mare viteză fără a utiliza blocări.

Cu toate acestea, există o altă modalitate de a paraleliza programele - unități de procesare grafică (GPU), având mai multe nuclee chiar și procesoare de înaltă performanță. Miezurile GPU sunt excelente pentru implementarea algoritmilor de procesare paralelă a datelor, iar numărul lor mare plătește mai mult decât inconvenientul de a rula programe pe ele. În acest articol ne vom familiariza cu una dintre modalitățile de a rula programe pe un GPU, folosind un set de extensii de limbaj C++ numite C++AMP.

Extensiile C++ AMP se bazează pe limbajul C++, motiv pentru care acest articol va demonstra exemple în C++. Cu toate acestea, cu utilizarea moderată a mecanismului de interacțiune în. NET, puteți utiliza algoritmi C++ AMP în programele dvs. .NET. Dar despre asta vom vorbi la sfârșitul articolului.

Introducere în C++ AMP

În esență, un GPU este același procesor ca oricare altul, dar cu un set special de instrucțiuni, un număr mare de nuclee și propriul protocol de acces la memorie. Cu toate acestea, există diferențe mari între GPU-urile moderne și procesoarele convenționale, iar înțelegerea acestora este esențială pentru a crea programe care să utilizeze eficient puterea de procesare a GPU-ului.

    GPU-urile moderne au un set de instrucțiuni foarte mic. Acest lucru implică unele limitări: lipsa capacității de a apela funcții, un set limitat de tipuri de date acceptate, lipsa funcțiilor de bibliotecă și altele. Unele operațiuni, cum ar fi ramurile condiționate, pot costa semnificativ mai mult decât operațiuni similare efectuate pe procesoarele convenționale. Evident, mutarea unor cantități mari de cod de la CPU la GPU în astfel de condiții necesită un efort semnificativ.

    Numărul de nuclee în GPU-ul mediu este semnificativ mai mare decât în ​​procesorul mediu convențional. Cu toate acestea, unele sarcini sunt prea mici sau nu pot fi împărțite în părți suficient de mari pentru a beneficia de GPU.

    Suportul de sincronizare între nucleele GPU care efectuează aceeași sarcină este foarte slab și complet absent între nucleele GPU care efectuează sarcini diferite. Această circumstanță necesită sincronizarea procesorului grafic cu un procesor convențional.

Apare imediat întrebarea: ce sarcini sunt potrivite pentru rezolvare pe un GPU? Rețineți că nu orice algoritm este potrivit pentru execuție pe un GPU. De exemplu, GPU-urile nu au acces la dispozitivele I/O, așa că nu veți putea îmbunătăți performanța unui program care elimină fluxuri RSS de pe Internet folosind un GPU. Cu toate acestea, mulți algoritmi de calcul pot fi transferați pe GPU și pot fi paralelizați masiv. Mai jos sunt câteva exemple de astfel de algoritmi (această listă nu este completă):

    ascuțirea și ascuțirea imaginilor și alte transformări;

    Transformare rapidă Fourier;

    transpunerea și înmulțirea matricei;

    sortarea numerelor;

    inversarea hash directă.

O sursă excelentă pentru exemple suplimentare este blogul Microsoft Native Concurrency, care oferă fragmente de cod și explicații pentru diverși algoritmi implementați în C++ AMP.

C++ AMP este un cadru inclus cu Visual Studio 2012 care oferă dezvoltatorilor C++ o modalitate ușoară de a efectua calcule pe GPU, necesitând doar un driver DirectX 11 Microsoft a lansat C++ AMP ca o specificație deschisă care poate fi implementată de orice furnizor de compilator.

Cadrul C++ AMP vă permite să rulați cod acceleratoare grafice, care sunt dispozitive de calcul. Folosind driverul DirectX 11, cadrul C++ AMP detectează în mod dinamic toate acceleratoarele. C++ AMP include, de asemenea, un emulator de accelerator software și un emulator convențional bazat pe procesor, WARP, care servește ca alternativă pentru sistemele fără GPU sau cu GPU, dar nu are un driver DirectX 11 și utilizează mai multe nuclee și instrucțiuni SIMD.

Acum să începem să explorăm un algoritm care poate fi ușor paralelizat pentru execuție pe un GPU. Implementarea de mai jos ia doi vectori de lungime egală și calculează rezultatul punctual. Este greu de imaginat ceva mai simplu:

Void VectorAddExpPointwise(float* primul, float* al doilea, float* rezultat, int lungime) (pentru (int i = 0; i< length; ++i) { result[i] = first[i] + exp(second[i]); } }

Pentru a paraleliza acest algoritm pe un procesor obișnuit, trebuie să împărțiți intervalul de iterație în mai multe subgagii și să rulați un fir de execuție pentru fiecare dintre ele. Am petrecut mult timp în articolele anterioare exact pe acest mod de a paraleliza primul nostru exemplu de căutare a numerelor prime - am văzut cum se poate realiza prin crearea manuală a firelor de execuție, transmiterea de joburi la un pool de fire și folosind Parallel.For și PLINQ să se paralelizeze automat. Amintiți-vă, de asemenea, că atunci când paralelizăm algoritmi similari pe un procesor convențional, am avut o grijă deosebită să nu împărțim problema în sarcini prea mici.

Pentru GPU, aceste avertismente nu sunt necesare. GPU-urile au mai multe nuclee care execută fire de execuție foarte rapid, iar costul comutării contextului este semnificativ mai mic decât procesoarele convenționale. Mai jos este un fragment care încearcă să folosească funcția paralel_pentru_fiecare din cadrul C++ AMP:

#include #include utilizarea simultană a spațiului de nume; void VectorAddExpPointwise(float* primul, float* al doilea, float* rezultat, lungime int) ( array_view avFirst(lungime, primul); array_view avSecond(lungime, secundă); array_view avResult(lungime, rezultat); avResult.discard_data(); parallel_for_each(avResult.extent, [=](index<1>i) restrict(amp) ( avResult[i] = avFirst[i] + fast_math::exp(avSecond[i]); )); avResult.synchronize(); )

Acum să examinăm fiecare parte a codului separat. Să observăm imediat că forma generală a buclei principale a fost păstrată, dar bucla for folosită inițial a fost înlocuită cu un apel la funcția parallel_for_each. De fapt, principiul conversiei unei bucle într-o funcție sau apel de metodă nu este nou pentru noi - o astfel de tehnică a fost demonstrată anterior folosind metodele Parallel.For() și Parallel.ForEach() din biblioteca TPL.

Apoi, datele de intrare (parametrii primul, al doilea și rezultatul) sunt împachetate cu instanțe array_view. Clasa array_view este folosită pentru a încheia datele transmise la GPU (accelerator). Parametrul său șablon specifică tipul de date și dimensiunea acestuia. Pentru a executa instrucțiuni pe un GPU care accesează date procesate inițial pe un procesor convențional, cineva sau ceva trebuie să aibă grijă să copieze datele pe GPU, deoarece majoritatea plăcilor grafice moderne sunt dispozitive separate cu propria memorie. Instanțele array_view rezolvă această problemă - oferă copierea datelor la cerere și numai atunci când este cu adevărat necesar.

Când GPU-ul finalizează sarcina, datele sunt copiate înapoi. Prin instanțierea array_view cu un argument const, ne asigurăm că primul și al doilea sunt copiați în memoria GPU, dar nu copiați înapoi. La fel, sunând aruncare_date(), excludem copierea rezultatului din memoria unui procesor obișnuit în memoria acceleratorului, dar aceste date vor fi copiate în direcția opusă.

Funcția parallel_for_each preia un obiect extent care specifică forma datelor de prelucrat și o funcție de aplicat fiecărui element din obiectul extent. În exemplul de mai sus, am folosit o funcție lambda, suport pentru care a apărut în standardul ISO C++2011 (C++11). Cuvântul cheie restrict (amp) instruiește compilatorul să verifice dacă corpul funcției poate fi executat pe GPU și dezactivează majoritatea sintaxei C++ care nu poate fi compilată în instrucțiunile GPU.

Parametrul funcției Lambda, index<1>obiect, reprezintă un index unidimensional. Trebuie să se potrivească cu obiectul extent utilizat - dacă ar fi să declarăm obiectul extent ca fiind bidimensional (de exemplu, prin definirea formei datelor sursă ca o matrice bidimensională), indexul ar trebui să fie, de asemenea, doi -dimensională. Un exemplu de astfel de situație este dat mai jos.

În cele din urmă, apelul de metodă sincroniza() la sfârșitul metodei VectorAddExpPointwise, se asigură că rezultatele calculului din array_view avResult, produse de GPU, sunt copiate înapoi în matricea de rezultate.

Aceasta încheie prima noastră introducere în lumea C++ AMP, iar acum suntem pregătiți pentru cercetări mai detaliate, precum și pentru exemple mai interesante care demonstrează beneficiile utilizării calculului paralel pe un GPU. Adăugarea vectorului nu este un algoritm bun și nu este cel mai bun candidat pentru demonstrarea utilizării GPU-ului din cauza supraîncărcării mari de copiere a datelor. Următoarea subsecțiune va arăta încă două exemple interesante.

Înmulțirea matricei

Primul exemplu „real” la care ne vom uita este înmulțirea matriceală. Pentru implementare, vom lua un algoritm simplu de multiplicare cu matrice cubică, și nu algoritmul Strassen, care are un timp de execuție apropiat de ~O cubic (n 2,807). Având în vedere două matrice, o matrice m x w A și o matrice w x n B, următorul program le va înmulți și va returna rezultatul, o matrice m x n C:

Void MatrixMultiply(int* A, int m, int w, int* B, int n, int* C) ( pentru (int i = 0; i< m; ++i) { for (int j = 0; j < n; ++j) { int sum = 0; for (int k = 0; k < w; ++k) { sum += A * B; } C = sum; } } }

Există mai multe moduri de a paraleliza această implementare, iar dacă doriți să paralelizați acest cod pentru a rula pe un procesor obișnuit, alegerea potrivită ar fi să paralelizați bucla exterioară. Cu toate acestea, GPU-ul are un număr destul de mare de nuclee, iar paralelizând doar bucla exterioară, nu vom putea crea un număr suficient de joburi pentru a încărca toate nucleele cu lucru. Prin urmare, are sens să paralelizezi cele două bucle exterioare, lăsând bucla interioară neatinsă:

Void MatrixMultiply (int* A, int m, int w, int* B, int n, int* C) ( array_view avA(m, w, A); array_view avB(w, n, B); array_view avC(m, n, C); avC.discard_data(); parallel_for_each(avC.extent, [=](index<2>idx) restrict(amp) ( int sum = 0; for (int k = 0; k< w; ++k) { sum + = avA(idx*w, k) * avB(k*w, idx); } avC = sum; }); }

Această implementare seamănă încă foarte mult cu implementarea secvențială a înmulțirii matricelor și a exemplului de adiție vectorială prezentat mai sus, cu excepția indexului, care este acum bidimensional și accesibil în bucla interioară folosind operatorul. Cât de mult este mai rapidă această versiune decât alternativa secvenţială care rulează pe un procesor obişnuit? Înmulțind două matrici (numere întregi) de dimensiunea 1024 x 1024, versiunea secvențială pe un procesor obișnuit durează în medie 7350 milisecunde, în timp ce versiunea GPU - ține-te bine - durează 50 de milisecunde, de 147 de ori mai rapid!

Simularea mișcării particulelor

Exemplele de rezolvare a problemelor pe GPU prezentate mai sus au o implementare foarte simplă a buclei interne. Este clar că acest lucru nu va fi întotdeauna cazul. Blogul Native Concurrency, legat mai sus, demonstrează un exemplu de modelare a interacțiunilor gravitaționale dintre particule. Simularea implică un număr infinit de pași; la fiecare pas, se calculează noi valori ale elementelor vectorului de accelerație pentru fiecare particulă și apoi se determină noile coordonate ale acestora. Aici, vectorul de particule este paralelizat - cu un număr suficient de mare de particule (de la câteva mii și mai sus), puteți crea un număr suficient de mare de sarcini pentru a încărca toate nucleele GPU cu lucru.

Baza algoritmului este implementarea determinării rezultatului interacțiunilor dintre două particule, așa cum se arată mai jos, care poate fi transferat cu ușurință pe GPU:

// aici float4 sunt vectori cu patru elemente // reprezentând particulele implicate în operațiunile void bodybody_interaction (float4& acceleration, const float4 p1, const float4 p2) restrict(amp) ( float4 dist = p2 – p1; // nu este folosit aici float absDist = dist.x*dist.x + dist.y*dist.y + dist.z*dist.z float invDist = 1.0f / sqrt(absDist) = invDist*invDist*; PARTICLE_MASS*invDistCube )

Datele inițiale la fiecare pas de modelare sunt o matrice cu coordonatele și vitezele mișcării particulelor și, ca rezultat al calculelor, este creată o nouă matrice cu coordonatele și vitezele particulelor:

Struct particulă ( poziție float4, viteza; // implementări ale constructorului, constructorului de copiere și // operatorului = cu restrict(amp) omis pentru a economisi spațiu); void simulation_step(matrice & anterior, matrice & următor, int corpuri) (extent<1>ext(corpuri); paralel_pentru_fiecare (ext, [&](index<1>idx) restrict(amp) (particulă p = anterioară; float4 acceleration(0, 0, 0, 0); for (int body = 0; body)< bodies; ++body) { bodybody_interaction (acceleration, p.position, previous.position); } p.velocity + = acceleration*DELTA_TIME; p.position + = p.velocity*DELTA_TIME; next = p; }); }

Cu ajutorul unei interfețe grafice adecvate, modelarea poate fi foarte interesantă. Exemplul complet oferit de echipa C++ AMP poate fi găsit pe blogul Native Concurrency. Pe sistemul meu cu un procesor Intel Core i7 și o placă grafică Geforce GT 740M, simularea a 10.000 de particule rulează la ~2,5 fps (pași pe secundă) folosind versiunea secvențială care rulează pe procesorul obișnuit și 160 fps folosind versiunea optimizată care rulează pe GPU - o creștere uriașă a performanței.

Înainte de a încheia această secțiune, mai există o caracteristică importantă a cadrului C++ AMP care poate îmbunătăți și mai mult performanța codului care rulează pe GPU. Suport GPU-uri memoria cache de date programabilă(adesea numit memorie partajată). Valorile stocate în acest cache sunt împărtășite de toate firele de execuție într-o singură piesă. Datorită plăcii de memorie, programele bazate pe framework-ul C++ AMP pot citi datele din memoria plăcii grafice în memoria partajată a mozaicului și apoi le accesează din mai multe fire de execuție fără a prelua datele din memoria plăcii grafice. Accesarea memoriei partajate din mozaic este de aproximativ 10 ori mai rapidă decât memoria plăcii grafice. Cu alte cuvinte, ai motive să continui să citești.

Pentru a oferi o versiune în mosaic a buclei paralele, este trecută metoda parallel_for_each domeniu tiled_extent, care împarte obiectul de extindere multidimensională în plăci multidimensionale și parametrul lambda tiled_index, care specifică ID-ul global și local al firului de execuție din tigla. De exemplu, o matrice de 16x16 poate fi împărțită în plăci de 2x2 (așa cum se arată în imaginea de mai jos) și apoi trecută la funcția parallel_for_each:

Măsură<2>matrice (16,16); tiled_extent<2,2>tiledMatrix = matrice.tigla<2,2>(); paralel_pentru_fiecare(tiledMatrix, [=](tiled_index<2,2>idx) restrict(amp) ( // ... ));

Fiecare dintre cele patru fire de execuție aparținând aceluiași mozaic poate partaja datele stocate în bloc.

La efectuarea operațiunilor cu matrice, în nucleul GPU, în locul indexului standard<2>, ca în exemplele de mai sus, puteți utiliza idx.global. Utilizarea corectă a memoriei locale și a indecșilor locali poate oferi câștiguri semnificative de performanță. Pentru a declara memoria tile partajată de toate firele de execuție într-un singur tile, variabilele locale pot fi declarate cu specificatorul tile_static.

În practică, tehnica de a declara memoria partajată și de a inițializa blocurile sale individuale în diferite fire de execuție este adesea folosită:

Parallel_for_each(tiledMatrix, [=](tiled_index<2,2>idx) restrict(amp) ( // 32 de octeți sunt partajați de toate firele din blocul tile_static int local; // atribuie o valoare elementului pentru acest fir de execuție local = 42; ));

Evident, orice beneficii din utilizarea memoriei partajate pot fi obținute numai dacă accesul la această memorie este sincronizat; adică firele de execuție nu trebuie să acceseze memoria până când aceasta nu a fost inițializată de unul dintre ele. Sincronizarea firelor într-un mozaic se realizează folosind obiecte țiglă_barieră(amintește de clasa Barrier din biblioteca TPL) - vor putea continua execuția numai după apelarea metodei tile_barrier.Wait(), care va returna controlul doar atunci când toate firele au numit tile_barrier.Wait. De exemplu:

Parallel_for_each(tiledMatrix, (tiled_index<2,2>idx) restrict(amp) ( // 32 de octeți sunt partajați de toate firele din blocul tile_static int local; // atribuie o valoare elementului pentru acest fir de execuție local = 42; // idx.barrier este o instanță a tile_barrier idx.barrier.wait(); // Acum acest thread poate accesa matricea "locală", // folosind indexurile altor fire de execuție ));

Acum este momentul să traduci ceea ce ai învățat într-un exemplu concret. Să revenim la implementarea înmulțirii matricelor, efectuată fără utilizarea organizării memoriei de tip tiling și să adăugăm optimizarea descrisă. Să presupunem că dimensiunea matricei este un multiplu de 256 - acest lucru ne va permite să lucrăm cu blocuri de 16 x 16. Natura matricelor permite înmulțirea bloc cu bloc și putem profita de această caracteristică (de fapt, împărțirea). matrices în blocuri este o optimizare tipică a algoritmului de multiplicare a matricei, oferind o utilizare mai eficientă a memoriei cache a CPU).

Esența acestei tehnici se rezumă la următoarele. Pentru a găsi C i,j (elementul din rândul i și coloana j din matricea rezultatului), trebuie să calculați produsul scalar dintre A i,* (i-lea rând al primei matrice) și B *,j (j) -a coloană din a doua matrice). Totuși, aceasta este echivalentă cu calcularea produselor punctiforme parțiale ale rândului și coloanei și apoi însumarea rezultatelor. Putem folosi acest fapt pentru a converti algoritmul de multiplicare a matricei într-o versiune de tiling:

Void MatrixMultiply(int* A, int m, int w, int* B, int n, int* C) ( array_view avA(m, w, A); array_view avB(w, n, B); array_view avC(m, n, C); avC.discard_data(); parallel_for_each(avC.extent.tile<16,16>(), [=](index_tiled<16,16>idx) restrict(amp) ( int sum = 0; int localRow = idx.local, localCol = idx.local; for (int k = 0; k

Esența optimizării descrise este că fiecare fir din mozaic (256 fire sunt create pentru un bloc de 16 x 16) își inițializează elementul în 16 x 16 copii locale ale fragmentelor matricelor originale A și B. Fiecare fir din mozaic necesită doar un rând și o coloană din aceste blocuri, dar toate firele împreună vor accesa fiecare rând și fiecare coloană de 16 ori. Această abordare reduce semnificativ numărul de accesări la memoria principală.

Pentru a calcula elementul (i,j) din matricea rezultatului, algoritmul necesită rândul i-lea complet al primei matrice și coloana j-a a celei de-a doua matrice. Când firele sunt 16x16 tiling reprezentate în diagramă și k=0, regiunile umbrite din prima și a doua matrice vor fi citite în memoria partajată. Elementul de calcul al firului de execuție (i,j) din matricea rezultat va calcula produsul punctual parțial al primelor k elemente din rândul i și coloana j a matricelor originale.

În acest exemplu, folosirea unei organizații cu plăci oferă o creștere uriașă a performanței. Versiunea în mosaic a înmulțirii matricelor este mult mai rapidă decât versiunea simplă, luând aproximativ 17 milisecunde (pentru aceleași matrici de intrare 1024 x 1024), ceea ce este de 430 de ori mai rapid decât versiunea care rulează pe un procesor convențional!

Înainte de a încheia discuția despre cadrul C++ AMP, am dori să menționăm instrumentele (în Visual Studio) disponibile pentru dezvoltatori. Visual Studio 2012 oferă un depanator al unității de procesare grafică (GPU) care vă permite să setați puncte de întrerupere, să examinați stiva de apeluri și să citiți și să modificați valorile variabilelor locale (unele acceleratoare acceptă direct depanarea GPU; pentru altele, Visual Studio utilizează un simulator software) , și un profiler care vă permite să evaluați beneficiile pe care le primește o aplicație din operațiunile de paralelizare folosind un GPU. Pentru mai multe informații despre capabilitățile de depanare în Visual Studio, consultați articolul Walkthrough. Depanarea unei aplicații C++ AMP" pe MSDN.

Alternative de calcul GPU în .NET

Până acum, acest articol a arătat doar exemple în C++, cu toate acestea, există mai multe moduri de a valorifica puterea GPU-ului în aplicațiile gestionate. O modalitate este să utilizați instrumente de interoperabilitate care vă permit să descărcați munca cu nuclee GPU către componentele C++ de nivel scăzut. Această soluție este excelentă pentru cei care doresc să folosească cadrul C++ AMP sau au capacitatea de a folosi componente C++ AMP pre-construite în aplicații gestionate.

O altă modalitate este să utilizați o bibliotecă care funcționează direct cu GPU-ul din codul gestionat. În prezent există mai multe astfel de biblioteci. De exemplu, GPU.NET și CUDAfy.NET (ambele oferte comerciale). Mai jos este un exemplu din depozitul GPU.NET GitHub care demonstrează implementarea produsului punctual a doi vectori:

Public static void MultiplyAddGpu(double a, double b, double c) ( int ThreadId = BlockDimension.X * BlockIndex.X + ThreadIndex.X; int TotalThreads = BlockDimension.X * GridDimension.X; for (int ElementIdx = ThreadId; ElementIdx

Sunt de părere că este mult mai ușor și mai eficient să înveți o extensie de limbaj (bazată pe C++ AMP) decât să încerci să orchestrezi interacțiunile la nivel de bibliotecă sau să faci modificări semnificative în limbajul IL.

Așadar, după ce am analizat posibilitățile de programare paralelă în .NET și utilizarea GPU-ului, nimeni nu se îndoiește că organizarea calculului paralel este o modalitate importantă de creștere a productivității. În multe servere și stații de lucru din întreaga lume, puterea neprețuită de procesare a procesoarelor și a GPU-urilor rămâne nefolosită deoarece aplicațiile pur și simplu nu o folosesc.

Biblioteca Task Parallel ne oferă o oportunitate unică de a include toate nucleele CPU disponibile, deși acest lucru va necesita rezolvarea unor probleme interesante de sincronizare, fragmentare excesivă a sarcinilor și distribuție inegală a muncii între firele de execuție.

Cadrul C++ AMP și alte biblioteci multifuncționale de calcul paralel GPU pot fi utilizate cu succes pentru a paraleliza calculele pe sute de nuclee GPU. În cele din urmă, există o oportunitate neexploratată anterior de a obține câștiguri de productivitate din utilizarea tehnologiilor de calcul distribuit în cloud, care au devenit recent una dintre direcțiile principale în dezvoltarea tehnologiei informației.

Caracteristici ale arhitecturii AMD/ATI Radeon

Acest lucru este similar cu nașterea unor noi specii biologice, când, în timpul dezvoltării habitatelor, ființele vii evoluează pentru a-și îmbunătăți adaptabilitatea la mediu. De asemenea, GPU-ul, începând cu accelerarea rasterizării și texturării triunghiurilor, a dezvoltat capacități suplimentare pentru executarea programelor shader pentru colorarea acestor triunghiuri. Și aceste abilități sunt solicitate și în calculul non-grafic, unde în unele cazuri oferă câștiguri semnificative de performanță în comparație cu soluțiile tradiționale.

Să tragem și alte analogii - după o evoluție îndelungată pe uscat, mamiferele au pătruns în mare, unde au strămutat locuitorii marini obișnuiți. În competiție, mamiferele au folosit atât abilități noi avansate care au apărut pe suprafața pământului, cât și cele dobândite special pentru adaptarea la viața în apă. De asemenea, GPU-urile, bazate pe punctele forte ale arhitecturii pentru grafica 3D, adaugă din ce în ce mai mult funcționalități specializate utile pentru sarcini non-grafice.

Deci, ce permite GPU-urilor să își revendice propriul sector în spațiul software de uz general? Microarhitectura GPU-ului este construită complet diferit de cea a procesoarelor convenționale și conține în mod inerent anumite avantaje. Sarcinile grafice necesită procesare paralelă independentă, iar GPU-ul este multi-threaded nativ. Dar acest paralelism îi aduce doar bucurie. Microarhitectura este concepută pentru a exploata numărul mare de fire disponibile care necesită execuție.

GPU-ul constă din câteva zeci de nuclee de procesor (30 pentru Nvidia GT200, 20 pentru Evergreen, 16 pentru Fermi), care se numesc Streaming Multiprocessor în terminologia Nvidia și SIMD Engine în terminologia ATI. În sensul acestui articol, le vom numi miniprocesoare, deoarece execută câteva sute de fire de execuție de program și pot face aproape tot ce poate face un procesor obișnuit, dar nu tot.

Numele de marketing sunt confuze - pentru o importanță mai mare, ele indică numărul de module funcționale care pot scădea și înmulți: de exemplu, 320 de „nuclee” vectoriale. Aceste sâmburi sunt mai mult ca boabele. Este mai bine să ne gândim la GPU ca la un fel de procesor multi-core cu un număr mare de nuclee care execută multe fire simultan.

Fiecare miniprocesor are memorie locală, 16 KB pentru GT200, 32 KB pentru Evergreen și 64 KB pentru Fermi (în esență un cache L1 programabil). Are un timp de acces similar cu primul nivel cache al unui procesor convențional și îndeplinește funcții similare pentru livrarea cea mai rapidă a datelor către modulele funcționale. În arhitectura Fermi, o parte din memoria locală poate fi configurată ca cache obișnuit. Într-un GPU, memoria locală este utilizată pentru schimbul rapid de date între firele de execuție. Una dintre schemele obișnuite ale unui program GPU este următoarea: în primul rând, datele din memoria globală a GPU sunt încărcate în memoria locală. Aceasta este doar o memorie video obișnuită, situată (cum ar fi memoria de sistem) separat de procesorul „său” - în cazul video, este lipită de mai multe cipuri pe PCB-ul plăcii video. În continuare, câteva sute de fire lucrează cu aceste date în memoria locală și scriu rezultatul în memoria globală, după care este transferat pe CPU. Este responsabilitatea programatorului să scrie instrucțiuni pentru încărcarea și descărcarea datelor din memoria locală. În esență, este partiționarea datelor [o sarcină specifică] pentru procesare paralelă. GPU-ul acceptă, de asemenea, instrucțiuni atomice de scriere/citire în memorie, dar acestea sunt ineficiente și sunt de obicei necesare în etapa finală pentru a „lipi” rezultatele calculelor tuturor miniprocesoarelor.

Memoria locală este comună tuturor firelor de execuție care se execută în miniprocesor, prin urmare, de exemplu, în terminologia Nvidia se numește chiar partajată, iar termenul memorie locală denotă exact opusul, și anume: o anumită zonă personală a unui fir separat. în memoria globală, vizibilă și accesibilă doar acesteia. Dar, pe lângă memoria locală, miniprocesorul are o altă zonă de memorie, care în toate arhitecturile este de aproximativ patru ori mai mare ca volum. Este împărțit în mod egal între toate firele de execuție, acestea sunt registre pentru stocarea variabilelor și a rezultatelor de calcul intermediare. Fiecare fir are câteva zeci de registre. Numărul exact depinde de câte fire rulează miniprocesorul. Acest număr este foarte important, deoarece latența memoriei globale este foarte mare, sute de cicluri, iar în absența cache-urilor nu există unde să stocați rezultatele intermediare ale calculelor.

Și încă o caracteristică importantă a GPU-ului: vectorizarea „soft”. Fiecare miniprocesor are un număr mare de module de calcul (8 pentru GT200, 16 pentru Radeon și 32 pentru Fermi), dar toate pot executa doar aceeași instrucțiune, cu aceeași adresă de program. În acest caz, operanzii pot fi diferiți, firele diferite au propriile lor. De exemplu, instrucțiuni adăugați conținutul a două registre: este executat simultan de toate dispozitivele de calcul, dar registrele sunt luate diferit. Se presupune că toate firele de execuție ale programului GPU, care efectuează procesare paralelă a datelor, se deplasează în general într-un curs paralel prin codul programului. Astfel, toate modulele de calcul sunt încărcate uniform. Și dacă firele de execuție diferă în calea lor de execuție a codului din cauza ramurilor din program, atunci are loc așa-numita serializare. Atunci nu sunt folosite toate modulele de calcul, deoarece firele de execuție trimit diverse instrucțiuni pentru execuție, iar un bloc de module de calcul poate executa, așa cum am spus deja, doar o instrucțiune cu o singură adresă. Și, desigur, productivitatea scade față de maxim.

Avantajul este că vectorizarea este complet automată, nu este programare folosind SSE, MMX și așa mai departe. Și GPU-ul însuși se ocupă de discrepanțe. Teoretic, în general, puteți scrie programe pentru GPU fără să vă gândiți la natura vectorială a modulelor de execuție, dar viteza unui astfel de program nu va fi foarte mare. Dezavantajul este lățimea mare a vectorului. Este mai mare decât numărul nominal de module funcționale și este de 32 pentru GPU-urile Nvidia și 64 pentru Radeon. Firele sunt procesate în blocuri de dimensiuni adecvate. Nvidia numește acest bloc de fire termenul warp, AMD îl numește wave front, ceea ce este același lucru. Astfel, pe 16 dispozitive de calcul, un „front de undă” cu o lungime de 64 de fire este procesat în patru cicluri de ceas (presupunând lungimea obișnuită a instrucțiunii). Autorul preferă termenul warp în acest caz, datorită asocierii cu termenul nautic warp, adică o frânghie legată între ele din funii răsucite. Deci firele „se răsucesc” și formează un mănunchi solid. Cu toate acestea, „frontul de valuri” poate fi asociat și cu marea: instrucțiunile ajung la dispozitive de acționare în același mod în care valurile se rostogolesc pe țărm unul după altul.

Dacă toate firele de execuție sunt la fel de avansate în execuția programului (situate în același loc) și astfel execută aceeași instrucțiune, atunci totul este în regulă, dar dacă nu, are loc încetinirea. În acest caz, firele dintr-un warp sau un front de undă sunt situate în locuri diferite în program, ele sunt împărțite în grupuri de fire care au aceeași valoare a numărului de instrucțiuni (cu alte cuvinte, indicatorul de instrucțiuni). Și numai firele unui grup sunt încă executate la un moment dat - toate execută aceeași instrucțiune, dar cu operanzi diferiți. Ca urmare, warp rulează de atâtea ori mai încet cât numărul de grupuri în care este împărțit, iar numărul de fire din grup nu contează. Chiar dacă grupul constă dintr-un singur fir, va dura totuși aceeași perioadă de timp pentru a se executa ca un warp complet. În hardware, acest lucru este implementat prin mascarea anumitor fire, adică instrucțiunile sunt executate în mod formal, dar rezultatele executării lor nu sunt înregistrate nicăieri și nu sunt folosite în viitor.

Deși la un moment dat fiecare miniprocesor (Streaming MultiProcessor sau SIMD Engine) execută instrucțiuni aparținând unui singur warp (o grămadă de fire), are câteva zeci de warp-uri active în pool-ul de execuție. După ce a executat instrucțiunile unui warp, miniprocesorul execută nu următoarea instrucțiune a firelor acestui warp, ci instrucțiunile unui alt warp. Acest warp poate fi într-un loc complet diferit în program, acest lucru nu va afecta viteza, deoarece numai în interiorul warp instrucțiunile tuturor firelor trebuie să fie aceleași pentru execuția la viteză maximă.

În acest caz, fiecare dintre cele 20 de motoare SIMD are patru fronturi de undă active, fiecare cu 64 de fire. Fiecare fir este indicat printr-o linie scurtă. Total: 64×4×20=5120 fire

Astfel, având în vedere că fiecare warp sau front de undă este format din 32-64 fire, miniprocesorul are câteva sute de fire active care se execută aproape simultan. Mai jos vom vedea ce beneficii arhitecturale promite un număr atât de mare de fire paralele, dar mai întâi vom lua în considerare ce limitări au miniprocesoarele care compun GPU-ul.

Principalul lucru este că GPU-ul nu are o stivă în care ar putea fi stocați parametrii funcției și variabilele locale. Datorită numărului mare de fire, pur și simplu nu există spațiu pe cip pentru stiva. Într-adevăr, deoarece GPU-ul execută simultan aproximativ 10.000 de fire, cu o dimensiune a stivei de un fir de 100 KB, volumul total va fi de 1 GB, ceea ce este egal cu cantitatea standard a întregii memorie video. Mai mult, nu există nicio modalitate de a plasa o stivă de orice dimensiune semnificativă în nucleul GPU în sine. De exemplu, dacă puneți 1000 de octeți de stivă pe un fir, atunci doar un miniprocesor ar necesita 1 MB de memorie, care este de aproape cinci ori cantitatea combinată de memorie locală a miniprocesorului și a memoriei alocate pentru stocarea registrelor.

Prin urmare, nu există recursivitate într-un program GPU și nu sunt multe de făcut cu apelurile de funcții. Toate funcțiile sunt introduse direct în cod la compilarea programului. Acest lucru limitează domeniul de aplicare al aplicațiilor GPU la sarcini de tip computațional. Uneori este posibil să se utilizeze o emulare limitată a stivei folosind memoria globală pentru algoritmi de recursivitate cu adâncimi mici de iterație cunoscute, dar aceasta nu este o aplicație GPU tipică. Pentru a face acest lucru, este necesar să se dezvolte în mod special un algoritm și să se exploreze posibilitatea implementării acestuia fără a garanta o accelerare de succes în comparație cu CPU.

Fermi a introdus pentru prima dată posibilitatea de a utiliza funcții virtuale, dar din nou utilizarea lor este limitată de lipsa unui cache mare și rapid pentru fiecare fir. 1536 fire reprezintă 48 KB sau 16 KB de L1, adică funcțiile virtuale dintr-un program pot fi folosite relativ rar, altfel stiva va folosi și memoria globală lentă, ceea ce va încetini execuția și, cel mai probabil, nu va aduce beneficii comparativ cu versiunea CPU.

Astfel, GPU-ul este reprezentat ca un coprocesor de calcul în care sunt încărcate datele, sunt procesate de un anumit algoritm, iar rezultatul este produs.

Beneficiile arhitecturii

Dar calculează GPU-ul foarte repede. Și multithreadingul său ridicat îl ajută în acest sens. Un număr mare de fire active face posibilă ascunderea parțială a latenței mari a memoriei video globale situate separat, care este de aproximativ 500 de cicluri de ceas. Este nivelat deosebit de bine pentru codul cu o densitate mare de operații aritmetice. Astfel, ierarhia cache L1-L2-L3 costisitoare pentru tranzistori nu este necesară. În schimb, mai multe module de calcul pot fi plasate pe cip, oferind performanțe aritmetice remarcabile. În timp ce instrucțiunile unui fir sau warp sunt executate, sutele rămase de fire își așteaptă în liniște datele.

Fermi a introdus un cache L2 de aproximativ 1 MB, dar nu poate fi comparat cu cache-urile procesoarelor moderne, este mai mult destinat comunicării între nuclee și diverse trucuri software. Dacă dimensiunea sa este împărțită între toate zecile de mii de fire, fiecare va avea un volum foarte neglijabil.

Dar, pe lângă latența globală a memoriei, există mult mai multe latențe într-un dispozitiv de calcul care trebuie ascunse. Aceasta este latența transferului de date pe cip de la dispozitivele de calcul către memoria cache de prim nivel, adică memoria locală a GPU-ului, și către registre, precum și cache-ul de instrucțiuni. Fișierul de registru, precum și memoria locală, sunt situate separat de modulele funcționale, iar viteza de acces la acestea este de aproximativ o duzină și jumătate de cicluri. Și din nou, un număr mare de fire, warps active, pot ascunde eficient această latență. Mai mult, lățimea de bandă totală de acces (lățimea de bandă) la memoria locală a întregului GPU, ținând cont de numărul de miniprocesoare care o compun, este semnificativ mai mare decât lățimea de bandă de acces la cache-ul de prim nivel al procesoarelor moderne. GPU-ul poate procesa mult mai multe date pe unitatea de timp.

Putem spune imediat că dacă GPU-ul nu este prevăzut cu un număr mare de fire paralele, atunci va avea performanțe aproape zero, deoarece va funcționa în același ritm ca și cum ar fi încărcat complet și va lucra mult mai puțin. De exemplu, să existe un singur fir în loc de 10.000: performanța va scădea de aproximativ o mie de ori, pentru că nu numai că nu vor fi încărcate toate blocurile, dar vor fi și afectate toate latențele.

Problema ascunderii latențelor este, de asemenea, acută pentru procesoarele moderne de înaltă frecvență pentru a o elimina - pipelining profund, execuția necorespunzătoare a instrucțiunilor; Acest lucru necesită programatoare complexe de instrucțiuni, diverse buffer-uri etc., care ocupă spațiu pe cip. Toate acestea sunt necesare pentru cea mai bună performanță cu un singur thread.

Dar toate acestea nu sunt necesare pentru GPU, ci sunt mai rapide din punct de vedere arhitectural pentru sarcini de calcul cu un număr mare de fire. Dar transformă multithreadingul în performanță, așa cum piatra filosofală transformă plumbul în aur.

GPU-ul a fost conceput inițial pentru execuția optimă a programelor shader pentru pixeli triunghi, care sunt evident independenți și pot fi executați în paralel. Și din această stare a evoluat prin adăugarea diferitelor capacități (memorie locală și acces adresabil la memoria video, precum și complicarea setului de instrucțiuni) într-un dispozitiv de calcul foarte puternic, care poate fi utilizat în mod eficient doar pentru algoritmi care permit implementarea extrem de paralelă folosind o cantitate limitată de memorie locală.

Exemplu

Una dintre cele mai clasice probleme pentru GPU este problema calculării interacțiunii dintre N corpuri creând un câmp gravitațional. Dar dacă, de exemplu, trebuie să calculăm evoluția sistemului Pământ-Lună-Soare, atunci GPU-ul este un ajutor prost pentru noi: sunt puține obiecte. Pentru fiecare obiect, este necesar să se calculeze interacțiunile cu toate celelalte obiecte și există doar două dintre ele. În cazul mișcării Sistemului Solar cu toate planetele și lunile lor (aproximativ câteva sute de obiecte), GPU-ul nu este încă foarte eficient. Cu toate acestea, din cauza supraîncărcării mari de gestionare a firelor, un procesor cu mai multe nuclee nu va putea afișa toată puterea și va funcționa în modul cu un singur fir. Dar dacă, de asemenea, trebuie să calculați traiectoriile cometelor și ale obiectelor centurii de asteroizi, atunci aceasta este deja o sarcină pentru GPU, deoarece există suficiente obiecte pentru a crea numărul necesar de fire de calcul paralele.

GPU-ul va funcționa bine, de asemenea, dacă trebuie să calculați coliziunile clusterelor globulare de sute de mii de stele.

O altă oportunitate de a utiliza puterea GPU într-o problemă cu N-corp apare atunci când trebuie să calculați multe probleme individuale, deși cu un număr mic de corpuri. De exemplu, dacă trebuie să calculați opțiuni pentru evoluția unui sistem pentru diferite opțiuni pentru viteze inițiale. Apoi puteți utiliza eficient GPU-ul fără probleme.

Detalii de microarhitectură AMD Radeon

Ne-am uitat la principiile de bază ale organizării GPU; acestea sunt comune pentru acceleratoarele video de la toți producătorii, deoarece inițial aveau o sarcină țintă - programele de shader. Cu toate acestea, producătorii au găsit o oportunitate de a diferi cu privire la detaliile implementării microarhitecturale. Deși procesoarele de la diferiți furnizori sunt uneori foarte diferite, chiar dacă sunt compatibile, cum ar fi Pentium 4 și Athlon sau Core. Arhitectura Nvidia este deja destul de cunoscută, acum ne vom uita la Radeon și vom evidenția principalele diferențe în abordările acestor furnizori.

Plăcile video AMD au primit suport complet pentru calcularea de uz general, începând cu familia Evergreen, care a implementat și specificațiile DirectX 11 pentru prima dată. Cardurile din familia 47xx au o serie de limitări semnificative, care vor fi discutate mai jos.

Diferențele de dimensiune a memoriei locale (32 KB pentru Radeon față de 16 KB pentru GT200 și 64 KB pentru Fermi) nu sunt în general semnificative. La fel și dimensiunea frontului de undă de 64 de fire pentru AMD față de 32 de fire în warp pentru Nvidia. Aproape orice program GPU poate fi ușor reconfigurat și ajustat la acești parametri. Performanța se poate schimba cu zeci de procente, dar în cazul unui GPU acest lucru nu este atât de important, deoarece un program GPU rulează de obicei de zece ori mai lent decât omologul său CPU, sau de zece ori mai rapid, sau nu funcționează deloc.

Mai importantă este utilizarea de către AMD a tehnologiei VLIW (Very Long Instruction Word). Nvidia folosește instrucțiuni scalare simple care funcționează pe registre scalare. Acceleratoarele sale implementează RISC clasic simplu. Plăcile video AMD au același număr de registre ca și GT200, dar registrele sunt vector pe 128 de biți. Fiecare instrucțiune VLIW operează pe mai multe registre cu patru componente pe 32 de biți, ceea ce este similar cu SSE, dar capacitățile VLIW sunt mult mai largi. Acesta nu este SIMD (Single Instruction Multiple Data) ca SSE - aici instrucțiunile pentru fiecare pereche de operanzi pot fi diferite și chiar dependente! De exemplu, să fie numite componentele registrului A a1, a2, a3, a4; registrul B este similar. Poate fi calculat cu o singură instrucțiune care se execută într-un singur ciclu de ceas, de exemplu, numărul a1×b1+a2×b2+a3×b3+a4×b4 sau un vector bidimensional (a1×b1+a2×b2, a3 ×b3+a4×b4).

Acest lucru a fost posibil datorită frecvenței mai mici a GPU-ului decât procesorului și reducerii puternice a tehnologiei de proces din ultimii ani. În acest caz, nu este necesar un planificator; aproape totul este executat într-un ciclu de ceas.

Datorită instrucțiunilor vectoriale, performanța maximă de precizie unică a Radeon este foarte ridicată, atingând teraflopi.

Un registru vectorial poate stoca un număr de precizie dublă în loc de patru numere de precizie simple. Și o instrucțiune VLIW poate fie să adauge două perechi de numere duble, fie să înmulțim două numere, fie să înmulțim două numere și să adunăm cu un al treilea. Astfel, performanța maximă în dublu este de aproximativ cinci ori mai mică decât în ​​float. Pentru modelele Radeon mai vechi, corespunde performanțelor Nvidia Tesla pe noua arhitectură Fermi și este mult mai mare decât performanța plăcilor duble pe arhitectura GT200. În plăcile video GeForce pentru consumatori bazate pe Fermi, viteza maximă a calculelor duble a fost redusă de patru ori.


Diagrama schematică a funcționării Radeon. Este prezentat doar un miniprocesor din 20 care rulează în paralel

Producătorii de GPU, spre deosebire de producătorii de procesoare (în primul rând cei compatibile cu x86), nu sunt legați de probleme de compatibilitate. Un program GPU este mai întâi compilat într-un cod intermediar, iar când programul rulează, driverul compilează acest cod în instrucțiuni de mașină specifice modelului. După cum s-a descris mai sus, producătorii de GPU-uri au profitat de acest lucru creând un ISA convenabil (Arhitectură de set de instrucțiuni) pentru GPU-urile lor și schimbându-le de la o generație la alta. În orice caz, acest lucru a adăugat un anumit procent de performanță din cauza absenței (ca inutil) a unui decodor. Dar AMD a mers și mai departe, creând propriul format pentru aranjarea instrucțiunilor în codul mașinii. Ele nu sunt aranjate secvenţial (conform listei de programe), ci pe secţiuni.

Mai întâi vine secțiunea de instrucțiuni de ramuri condiționate, care au legături către secțiuni de instrucțiuni aritmetice continue corespunzătoare diferitelor ramuri de ramuri. Se numesc pachete VLIW. Aceste secțiuni conțin doar instrucțiuni aritmetice cu date din registre sau din memoria locală. Această organizare simplifică gestionarea fluxului de instrucțiuni și livrarea acestora către dispozitivele executive. Acest lucru este cu atât mai util cu cât instrucțiunile VLIW au dimensiuni relativ mari. Există, de asemenea, secțiuni pentru instrucțiuni de acces la memorie.

Secțiuni de instrucțiuni de sărituri condiționate
Secțiunea 0Ramura 0Link către secțiunea 3 a instrucțiunilor de aritmetică continuă
Sectiunea 1Filiala 1Link către secțiunea nr. 4
Sectiunea 2Ramura 2Link către secțiunea nr. 5
Secțiuni de instrucție aritmetică continuă
Secțiunea 3Instrucțiunea VLIW 0Instrucțiunea VLIW 1Instrucțiunea VLIW 2Instrucțiunea VLIW 3
Secțiunea 4Instrucțiunea VLIW 4Instrucțiunea VLIW 5
Secțiunea 5Instrucțiunea VLIW 6Instrucțiunea VLIW 7Instrucțiunea VLIW 8Instrucțiunea VLIW 9

GPU-urile atât de la Nvidia, cât și de la AMD au, de asemenea, instrucțiuni încorporate pentru a calcula rapid funcțiile matematice de bază, rădăcină pătrată, exponent, logaritmi, sinusuri și cosinus pentru numere cu precizie unică în câteva cicluri de ceas. Există unități de calcul speciale pentru aceasta. Ele „procesează” din necesitatea de a implementa o aproximare rapidă a acestor funcții în geometrie shaders.

Chiar dacă cineva nu știa că GPU-urile sunt folosite pentru grafică și citește doar caracteristicile tehnice, atunci după acest semn ar putea ghici că aceste coprocesoare de calcul provin din acceleratoarele video. De asemenea, pe baza anumitor trăsături ale mamiferelor marine, oamenii de știință și-au dat seama că strămoșii lor erau creaturi terestre.

Dar o caracteristică mai evidentă care dezvăluie originea grafică a dispozitivului este unitățile de citire a texturii 2D și 3D cu suport pentru interpolare biliniară. Ele sunt utilizate pe scară largă în programele GPU, deoarece oferă citire accelerată și simplificată a matricelor de date doar pentru citire. Unul dintre comportamentele standard ale unei aplicații GPU este de a citi matrice de date sursă, de a le procesa în nucleele de calcul și de a scrie rezultatul într-o altă matrice, care este apoi transferat înapoi la CPU. Această schemă este standard și comună, deoarece este convenabilă pentru arhitectura GPU. Sarcinile care necesită citiri și scrieri intensive într-o regiune mare a memoriei globale, conținând astfel dependențe de date, sunt dificil de paralelizat și implementat eficient pe GPU. De asemenea, performanța lor va depinde în mare măsură de latența memoriei globale, care este foarte mare. Dar dacă sarcina este descrisă de modelul „citirea datelor - procesarea - scrierea rezultatului”, atunci aproape sigur puteți obține un impuls mare din executarea acesteia pe GPU.

Pentru datele de textură din GPU, există o ierarhie separată de cache-uri mici de primul și al doilea nivel. Acesta este ceea ce asigură accelerarea utilizării texturilor. Această ierarhie a apărut inițial în GPU-uri pentru a profita de localitatea de acces la texturi: evident, după procesarea unui pixel, un pixel vecin (cu o probabilitate mare) va necesita date de textura din apropiere. Dar mulți algoritmi pentru calcule convenționale au o natură similară a accesului la date. Deci, cache-urile de texturi din grafică vor fi foarte utile.

Deși dimensiunea cache-urilor L1-L2 din plăcile Nvidia și AMD este aproximativ similară, ceea ce este cauzat, evident, de cerințele de optimitate în ceea ce privește grafica jocului, latența de acces la aceste cache-uri variază semnificativ. Nvidia are o latență de acces mai mare, iar memoria cache a texturilor din GeForce ajută în primul rând la reducerea încărcării magistralei de memorie, mai degrabă decât la accelerarea directă a accesului la date. Acest lucru nu este vizibil în programele de grafică, dar este important pentru programele de uz general. În Radeon, latența cache-ului texturii este mai mică, dar latența memoriei locale a miniprocesoarelor este mai mare. Putem da următorul exemplu: pentru multiplicarea optimă a matricei pe cardurile Nvidia, este mai bine să folosiți memoria locală, încărcând acolo matricea bloc cu bloc, în timp ce pentru AMD este mai bine să vă bazați pe un cache de textură cu latență scăzută, citind elementele matricei după cum este necesar. Dar aceasta este deja o optimizare destul de subtilă și pentru un algoritm care a fost deja transferat fundamental pe GPU.

Această diferență apare și atunci când utilizați texturi 3D. Unul dintre primele benchmark-uri de calcul GPU, care a arătat un avantaj serios pentru AMD, a folosit texturi 3D, deoarece a funcționat cu o matrice de date tridimensională. Iar latența accesului la texturi în Radeon este semnificativ mai rapidă, iar carcasa 3D este, de asemenea, mai optimizată în hardware.

Pentru a obține performanțe maxime de la hardware de la diverse companii, este necesară o anumită reglare a aplicației pentru o anumită placă, dar acesta este un ordin de mărime mai puțin semnificativ decât dezvoltarea unui algoritm pentru arhitectura GPU în principiu.

Limitări ale seriei Radeon 47xx

În această familie, suportul pentru calcularea GPU este incomplet. Pot fi remarcate trei puncte importante. În primul rând, nu există memorie locală, adică este fizic acolo, dar nu are accesul universal cerut de standardul modern al programelor GPU. Este emulat în software-ul din memoria globală, ceea ce înseamnă că utilizarea sa, spre deosebire de un GPU cu funcții complete, nu va aduce beneficii. Al doilea punct este suportul limitat pentru diferitele instrucțiuni de operare a memoriei atomice și instrucțiuni de sincronizare. Iar al treilea punct este dimensiunea destul de mică a cache-ului de instrucțiuni: pornind de la o anumită dimensiune a programului, viteza încetinește semnificativ. Există și alte restricții minore. Putem spune că doar programele potrivite ideal pentru GPU vor funcționa bine pe această placă video. Deși în programele de testare simple care funcționează doar cu registre, o placă video poate da rezultate bune în Gigaflops, este problematic să programezi eficient ceva complex pentru ea.

Avantajele și dezavantajele Evergreen

Dacă compari produsele AMD și Nvidia, din perspectiva GPU-ului, seria 5xxx arată ca un GT200 foarte puternic. Atât de puternic încât îl depășește pe Fermi în performanță de vârf de aproximativ două ori și jumătate. Mai ales după ce parametrii noilor plăci video Nvidia au fost tăiați și numărul de nuclee a fost redus. Dar introducerea unui cache L2 în Fermi simplifică implementarea unor algoritmi pe GPU, extinzând astfel domeniul de aplicare al GPU-ului. Interesant este că pentru programele CUDA care au fost bine optimizate pentru generația anterioară GT200, inovațiile arhitecturale de la Fermi nu au dat adesea nimic. Au accelerat proporțional cu creșterea numărului de module de calcul, adică de mai puțin de două ori (pentru numere cu precizie unică), sau chiar mai puțin, deoarece lățimea de bandă a memoriei nu a crescut (sau din alte motive).

Și în sarcinile care se potrivesc bine arhitecturii GPU și au o natură vectorială pronunțată (de exemplu, multiplicarea matricei), Radeon arată performanțe relativ apropiate de vârful teoretic și îl depășește pe Fermi. Ca să nu mai vorbim de procesoarele multi-core. Mai ales în problemele cu numere de precizie unică.

Dar Radeon are o suprafață mai mică a matriței, mai puțină disipare a căldurii, consum de energie, randament mai mare și, în consecință, costuri mai mici. Și direct în sarcinile de grafică 3D, câștigul lui Fermi, dacă există, este mult mai mic decât diferența din zona cristalului. Acest lucru se datorează în mare parte faptului că arhitectura de calcul Radeon cu 16 unități de calcul per miniprocesor, o dimensiune a frontului de undă de 64 de fire și instrucțiuni vectoriale VLIW este excelentă pentru sarcina sa principală - calcularea shaderelor grafice. Pentru marea majoritate a utilizatorilor obișnuiți, performanța jocurilor și prețul sunt priorități.

Dintr-o perspectivă software profesională, științifică, arhitectura Radeon oferă cea mai bună performanță preț-performanță, performanță pe watt și performanță absolută pentru sarcini care sunt în mod inerent potrivite cu arhitecturile GPU, permițând paralelizarea și vectorizarea.

De exemplu, într-o sarcină de selecție a cheilor complet paralelă, ușor vectorizabilă, Radeon este de câteva ori mai rapid decât GeForce și de câteva zeci de ori mai rapid decât CPU.

Acest lucru este în concordanță cu conceptul general al AMD Fusion, conform căruia GPU-urile ar trebui să completeze procesorul și, în viitor, să fie integrate în nucleul procesorului însuși, la fel cum coprocesorul matematic a fost mutat anterior de la un cip separat la nucleul procesorului (acest lucru). s-a întâmplat în urmă cu douăzeci de ani, înainte de apariția primelor procesoare Pentium). GPU-ul va fi un nucleu grafic integrat și un coprocesor vectorial pentru sarcinile de streaming.

Radeon folosește o tehnică inteligentă de amestecare a instrucțiunilor din diferite fronturi de undă atunci când este executată de modulele funcționale. Acest lucru este ușor de făcut, deoarece instrucțiunile sunt complet independente. Principiul este similar cu execuția prin pipeline a instrucțiunilor independente de către procesoarele moderne. Aparent, acest lucru face posibilă executarea eficientă a instrucțiunilor VLIW vectoriale complexe, cu mai mulți octeți. Într-un procesor, acest lucru necesită un planificator sofisticat pentru a identifica instrucțiuni independente sau utilizarea tehnologiei Hyper-Threading, care furnizează, de asemenea, procesorului instrucțiuni deliberat independente de la diferite fire.

masura 0bara 1masura 2masura 3masura 4masura 5bara 6masura 7Modulul VLIW
frontul de undă 0frontul de undă 1frontul de undă 0frontul de undă 1frontul de undă 0frontul de undă 1frontul de undă 0frontul de undă 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. unsprezeceVLIW11
instr. 12VLIW12
instr. 13VLIW13
instr. 14VLIW14
instr. 15VLIW15

128 de instrucțiuni a două fronturi de undă, fiecare dintre ele constând din 64 de operații, sunt executate de 16 module VLIW în opt cicluri de ceas. Intercalarea are loc, iar fiecare modul are în realitate două cicluri de ceas pentru a executa o instrucțiune întreagă, cu condiția ca la al doilea ciclu de ceas să înceapă să execute unul nou în paralel. Acest lucru ajută probabil la executarea rapidă a unei instrucțiuni VLIW precum a1×a2+b1×b2+c1×c2+d1×d2, adică executarea a opt astfel de instrucțiuni în opt cicluri de ceas. (În mod oficial, se dovedește a fi unul pe măsură.)

Nvidia se pare că nu are o astfel de tehnologie. Și în absența VLIW, performanța înaltă folosind instrucțiuni scalare necesită funcționare de înaltă frecvență, care crește automat disiparea căldurii și impune procese mari cerințe (pentru a forța circuitul să funcționeze la o frecvență mai mare).

Dezavantajul lui Radeon din punctul de vedere al calculului GPU este marea antipatie pentru ramificare. GPU-urile, în general, nu favorizează ramificarea datorită tehnologiei descrise mai sus pentru executarea instrucțiunilor: dintr-o dată într-un grup de fire cu o singură adresă de program. (Apropo, această tehnică se numește SIMT: Single Instruction - Multiple Threads (o instrucțiune - mai multe fire), prin analogie cu SIMD, unde o instrucțiune efectuează o operație cu date diferite.) Cu toate acestea, lui Radeon nu îi place în mod special ramificarea: aceasta este cauzată de dimensiunea mai mare a mănunchiului de fire . Este clar că, dacă programul nu este complet vector, atunci cu cât dimensiunea warp sau a frontului de undă este mai mare, cu atât mai rău, deoarece atunci când firele învecinate diverg în căile programului lor, se formează mai multe grupuri care trebuie executate secvenţial (serializate). Să presupunem că toate firele sunt împrăștiate, atunci dacă dimensiunea warp este de 32 de fire, programul va funcționa de 32 de ori mai lent. Și în cazul mărimii 64, ca și în Radeon, este de 64 de ori mai lent.

Aceasta este o manifestare notabilă, dar nu singura, a „ostilității”. În plăcile video Nvidia, fiecare modul funcțional, altfel numit nucleu CUDA, are o unitate specială de procesare a ramurilor. Și în plăcile video Radeon cu 16 module de calcul există doar două unități de control al ramurilor (sunt eliminate din domeniul unităților aritmetice). Deci, chiar și procesarea simplă a unei instrucțiuni de salt condiționat, chiar dacă rezultatul acesteia este același pentru toate firele din frontul de undă, necesită timp suplimentar. Iar viteza scade.

AMD produce, de asemenea, procesoare. Ei cred că pentru programele cu un număr mare de ramuri, procesorul este încă mai potrivit, în timp ce GPU-ul este destinat programelor pur vector.

Deci, Radeon oferă o eficiență generală de programare mai mică, dar oferă un preț/performanță mai bun în multe cazuri. Cu alte cuvinte, există mai puține programe care pot fi migrate eficient (profitabil) de la un CPU la un Radeon decât există programe care pot rula eficient pe Fermi. Dar cele care pot fi transferate eficient vor funcționa mai eficient pe Radeon în multe feluri.

API pentru calcularea GPU

Specificațiile tehnice ale Radeon în sine arată atractiv, deși nu este nevoie să idealizați și să absolutizați calcularea GPU. Dar nu mai puțin important pentru productivitate este software-ul necesar pentru dezvoltarea și executarea unui program GPU - compilatoare dintr-un limbaj de nivel înalt și run-time, adică un driver care interacționează între partea programului care rulează pe CPU și GPU în sine. Este chiar mai important decât în ​​cazul unui CPU: CPU nu are nevoie de un driver pentru a gestiona transferurile de date, iar din punctul de vedere al compilatorului, GPU-ul este mai pretențios. De exemplu, compilatorul trebuie să se mulțumească cu un număr minim de registre pentru a stoca rezultatele intermediare ale calculelor și, de asemenea, să integreze cu atenție apelurile de funcții, folosind din nou un minim de registre. La urma urmei, cu cât folosește mai puține registre, cu atât pot fi lansate mai multe fire și cu atât GPU-ul poate fi încărcat mai complet, ascund mai bine timpul de acces la memorie.

Iar suportul software pentru produsele Radeon rămâne în urmă cu dezvoltarea hardware. (Spre deosebire de situația cu Nvidia, unde lansarea hardware-ului a fost amânată și produsul a fost lansat într-o formă redusă.) Recent, compilatorul OpenCL produs de AMD avea statut beta, cu multe defecte. A generat cod eronat prea des sau a refuzat să compileze codul din codul sursă corect sau a dat o eroare și s-a prăbușit. Abia la sfârșitul primăverii a fost lansată o versiune cu performanță ridicată. De asemenea, nu este lipsit de erori, dar sunt semnificativ mai puține dintre ele și tind să apară în direcții laterale atunci când încercați să programați ceva în pragul corectitudinii. De exemplu, funcționează cu tipul uchar4, care definește o variabilă cu patru componente de 4 octeți. Acest tip este în specificațiile OpenCL, dar nu merită să lucrezi cu el pe Radeon, deoarece registrele sunt pe 128 de biți: aceleași patru componente, dar pe 32 de biți. Și o astfel de variabilă uchar4 va ocupa în continuare un întreg registru, va necesita doar operațiuni suplimentare de împachetare și acces la componentele de octeți individuale. Compilatorul nu ar trebui să aibă erori, dar nu există compilatoare fără defecte. Chiar și Intel Compiler după 11 versiuni are erori de compilare. Erorile identificate sunt corectate în următoarea ediție, care va fi lansată mai aproape de toamnă.

Dar există încă multe lucruri care trebuie îmbunătățite. De exemplu, driverul GPU Radeon standard încă nu acceptă calculul GPU folosind OpenCL. Utilizatorul trebuie să descarce și să instaleze un pachet special suplimentar.

Dar cel mai important lucru este absența oricăror biblioteci de funcții. Pentru numerele reale cu precizie dublă nu există nici măcar un sinus, cosinus sau exponent. Ei bine, acest lucru nu este necesar pentru adunarea și înmulțirea matricei, dar dacă doriți să programați ceva mai complex, trebuie să scrieți toate funcțiile de la zero. Sau așteptați o nouă lansare SDK. ACML (AMD Core Math Library) pentru familia GPU Evergreen cu suport pentru funcțiile matriceale de bază ar trebui să fie lansat în curând.

În momentul de față, potrivit autorului articolului, pare fezabilă utilizarea API-ului Direct Compute 5.0 pentru programarea plăcilor video Radeon, ținând cont de limitările: țintirea platformei Windows 7 și Windows Vista. Microsoft are o experiență vastă în crearea de compilatoare și ne putem aștepta la o lansare complet funcțională foarte curând, Microsoft este direct interesat de acest lucru. Dar Direct Compute este axat pe nevoile aplicațiilor interactive: pentru a calcula ceva și a vizualiza imediat rezultatul - de exemplu, fluxul de lichid pe o suprafață. Acest lucru nu înseamnă că nu poate fi folosit pur și simplu pentru calcule, dar acesta nu este scopul său natural. Să presupunem că Microsoft nu intenționează să adauge funcții de bibliotecă la Direct Compute - doar acelea pe care AMD nu le are în prezent. Adică ceea ce acum poate fi calculat eficient pe Radeon - unele programe nu foarte sofisticate - poate fi implementat și pe Direct Compute, care este mult mai simplu decât OpenCL și ar trebui să fie mai stabil. În plus, este complet portabil și va rula atât pe Nvidia, cât și pe AMD, așa că trebuie să compilați programul o singură dată, în timp ce implementările Nvidia și OpenCL SDK de la AMD nu sunt pe deplin compatibile. (În sensul că, dacă dezvoltați un program OpenCL pe un sistem AMD folosind SDK-ul AMD OpenCL, s-ar putea să nu ruleze la fel de ușor pe Nvidia. Poate fi necesar să compilați același text folosind SDK-ul Nvidia. Și, bineînțeles, invers .)

Apoi, există o mulțime de funcționalități redundante în OpenCL, deoarece OpenCL este destinat să fie un limbaj de programare universal și API pentru o gamă largă de sisteme. Și GPU, și CPU și Cell. Deci, în cazul în care trebuie doar să scrieți un program pentru un sistem de utilizator tipic (procesor plus placă video), OpenCL nu pare să fie „foarte productiv”, ca să spunem așa. Fiecare funcție are zece parametri, iar nouă dintre ei trebuie setați la 0. Și pentru a seta fiecare parametru, trebuie să apelați o funcție specială, care are și parametri.

Și cel mai important avantaj actual al Direct Compute este că utilizatorul nu trebuie să instaleze un pachet special: tot ceea ce este necesar este deja în DirectX 11.

Probleme de dezvoltare a calculatoarelor GPU

Dacă luăm sfera computerelor personale, situația este următoarea: nu sunt multe sarcini care necesită o putere mare de calcul și un procesor dual-core convențional lipsește foarte mult. Era ca și cum monștri mari, voraci, dar stângaci s-ar fi târât din mare pe uscat, iar pe uscat nu era aproape nimic de mâncare. Și locuințele primordiale de pe suprafața pământului sunt în scădere în dimensiune, învățând să consume mai puțin, așa cum se întâmplă întotdeauna când există o lipsă de resurse naturale. Dacă ar exista aceeași nevoie de performanță acum ca acum 10-15 ani, calcularea GPU ar fi un mare succes. Și astfel ies în prim-plan problemele de compatibilitate și complexitatea relativă a programării GPU. Este mai bine să scrieți un program care rulează pe toate sistemele decât un program care rulează rapid, dar rulează doar pe GPU.

Perspectivele pentru GPU-uri sunt oarecum mai bune în ceea ce privește utilizarea în aplicații profesionale și în sectorul stațiilor de lucru, deoarece există o nevoie mai mare de performanță acolo. Apar plugin-uri pentru editorii 3D cu suport GPU: de exemplu, pentru randarea folosind ray tracing - a nu fi confundat cu randarea GPU obișnuită! De asemenea, apare ceva pentru editorii 2D și de prezentare, cu crearea mai rapidă a efectelor complexe. Programele de procesare video câștigă treptat suport pentru GPU. Sarcinile de mai sus, datorită naturii lor paralele, se potrivesc bine cu arhitectura GPU-ului, dar acum a fost creată, depanată și optimizată o bază de cod foarte mare, depanată și optimizată pentru toate capacitățile CPU, așa că va dura timp pentru ca implementările GPU bune să apară .

În acest segment, apar și astfel de puncte slabe ale GPU-urilor, cum ar fi cantitatea limitată de memorie video - aproximativ 1 GB pentru GPU-urile convenționale. Unul dintre principalii factori care reduc performanța programelor GPU este necesitatea de a face schimb de date între CPU și GPU printr-o magistrală lentă, iar din cauza memoriei limitate, trebuie transferate mai multe date. Și aici conceptul AMD de a combina GPU și CPU într-un singur modul pare promițător: puteți sacrifica lățimea de bandă mare a memoriei grafice pentru acces ușor și simplu la memoria partajată și cu o latență mai mică. Această lățime de bandă mare a memoriei video DDR5 actuale este mult mai solicitată direct de la programele grafice decât de la majoritatea programelor de calcul GPU. În general, memoria partajată a GPU-ului și procesorului va extinde pur și simplu în mod semnificativ domeniul de aplicare al GPU-ului, făcând posibilă utilizarea capacităților sale de calcul în subsarcini mici ale programelor.

Iar GPU-urile sunt cele mai căutate în domeniul calculului științific. Au fost deja construite mai multe supercalculatoare bazate pe GPU, care arată rezultate foarte mari în testul operațiunilor cu matrice. Problemele științifice sunt atât de diverse și numeroase încât există întotdeauna multe care se încadrează perfect în arhitectura GPU, pentru care utilizarea unui GPU facilitează obținerea de performanțe ridicate.

Dacă alegeți una dintre toate sarcinile computerelor moderne, aceasta va fi grafica pe computer - imaginea lumii în care trăim. Și arhitectura optimă în acest scop nu poate fi rea. Aceasta este o sarcină atât de importantă și fundamentală, încât hardware-ul special conceput pentru aceasta trebuie să fie universal și optim pentru diverse sarcini. Mai mult, plăcile video evoluează cu succes.