CUDA

Матеріал з Вікіпедії — вільної енциклопедії.
Перейти до: навігація, пошук
CUDA
Розробник(и) NVIDIA Corporation
Стабільний випуск 2.2 (7 травня 2009)
Операційна система Windows Vista, Windows XP, Windows Server 2008, Windows Server 2003, Linux, Mac OS X
Тип GPGPU
Ліцензія власницьке ПЗ
Сайт Nvidia's CUDA

CUDA(англ. Compute Unified Device Architecture) - програмно-апаратна архітектура паралельних обчислень, яка дозволяє істотно збільшити обчислювальну продуктивність завдяки використанню графічних процесорів фірми Nvidia. CUDA SDK дозволяє програмістам реалізовувати на спеціальному спрощеному діалекті мови програмування С алгоритми, здійснювані на графічних процесорах Nvidia, і включати спеціальні функції в текст програми на С. Архітектура CUDA дає розробнику можливість на свій розсуд організовувати доступ до набору інструкцій графічного прискорювача і управляти його пам'яттю. Первинна версія CUDA SDK була представлена 15 лютого 2007 року. У основі CUDA API лежить розширена мова C. Для успішної трансляції коду цією мовою, до складу CUDA SDK входить власний C-компілятор командного рядка nvcc компанії Nvidia. Компілятор nvcc створений на основі відкритого компілятора

Паралельні обчислення з CUDA[ред.ред. код]

Напрямок обчислень еволюціонує від «централізованої обробки даних» на центральному процесорі до «спільної обробки» на CPU і GPU. Для реалізації нової обчислювальної парадигми компанія NVIDIA винайшла архітектуру паралельних обчислень CUDA, на даний момент представлену в графічних процесорах GeForce, ION, Quadro і Tesla і забезпечує необхідну базу розробникам ПЗ. Говорячи про споживчому ринку, варто зазначити, що майже всі основні програми для роботи з відео вже обладнані, або будуть оснащені підтримкою CUDA-прискорення, включаючи продукти від Elemental Technologies, MotionDSP і LoiLo. Область наукових досліджень з великим ентузіазмом зустріла технологію CUDA. Приміром, зараз CUDA прискорює AMBER, програму для моделювання молекулярної динаміки, використовувану більше 60000 дослідниками в академічному середовищі і фармацевтичними компаніями по всьому світу для скорочення термінів створення лікарських препаратів.

На фінансовому ринку компанії Numerix і CompatibL анонсували підтримку CUDA в новому додатку аналізу ризику контрагентів і досягли прискорення роботи в 18 разів. Numerix використовується майже 400 фінансовими інститутами. Показником зростання застосування CUDA є також зростання використання графічних процесорів Tesla в GPU обчисленнях. На даний момент більше 700 GPU кластерів встановлені по всьому світу в компаніях зі списку Fortune 500, таких як Schlumberger і Chevron в енергетичному секторі, а також BNP Paribas в секторі банківських послуг. Завдяки нещодавно випущеним системам Microsoft Windows 7 і Apple Snow Leopard, обчислення на GPU займуть свої позиції в секторі масових рішень. У цих нових операційних системах GPU постане не тільки графічним процесором, але також і універсальним процесором для паралельних обчислень, що працюють з будь-яким додатком.

Платформа паралельних обчислень CUDA[ред.ред. код]

Платформа паралельних обчислень CUDA® забезпечує набір розширень для мов C і С++, що дозволяють висловлювати як паралелізм даних, так і паралелізм завдань на рівні дрібних і великих структурних одиниць. Програміст може вибрати засоби розробки: мови високого рівня, такі як C, C++, Fortran або ж відкриті стандарти, такі як директиви OpenACC. Платформа паралельних обчислень CUDA використовується на сьогоднішній день в тисячах GPU-прискорених додатків і тисячах опублікованих наукових статтях. Повний список засобів розробки і екосистема рішень CUDA доступний розробникам. Відвідайте портал CUDA Zone, щоб дізнатися більше про розробки з CUDA. Щоб отримати більш детальну інформацію про те, як почати роботу з паралельними обчисленнями або останніми версіями CUDA, які можна скачати, відвідайте CUDA Developer Zone.

Програмна архітектура[ред.ред. код]

Первісна версія CUDA SDK була представлена ​​15 лютого 2007. В основі інтерфейсу програмування додатків CUDA лежить мова С з деякими розширеннями. Для успішної трансляції коду на цій мові до складу CUDA SDK входить власний С-компілятор командного рядка nvcc компанії Nvidia. Компілятор nvcc створений на основі відкритого компілятора Open64 і призначений для трансляції host-коду (головного, керуючого коду) і device-коду (апаратного коду) (файлів з розширенням .cu) в об'єктні файли, придатні в процесі складання кінцевої програми або бібліотеки у середовищі програмування, наприклад, в NetBeans. В архітектурі CUDA використовується модель пам'яті GRID, кластерне моделювання потоків і SIMD-інструкції. Застосовна не тільки для високопродуктивних графічних обчислень, але і для різних наукових обчислень з використанням відеокарт nVidia. Учені і дослідники широко використовують CUDA в різних областях, включаючи астрофізику, обчислювальну біологію та хімію, моделювання динаміки рідин, електромагнітних взаємодій, комп'ютерну томографію, сейсмічний аналіз і багато іншого. У CUDA є можливість підключення до додатків, що використовують OpenGL і Direct3D. CUDA - кросплатформленість для таких операційних систем як Linux, Mac OS X і Windows. 22 березня 2010 nVidia випустила CUDA Toolkit 3.0, який містив підтримку OpenCL.

Переваги CUDA[ред.ред. код]

У порівнянні з традиційним підходом до організації обчислень загального призначення допомогою можливостей графічних API, у архітектури CUDA відзначають наступні переваги в цій області:

  1. Інтерфейс програмування додатків CUDA (CUDA API) заснований на стандартній мові програмування Сі з деякими обмеженнями. На думку розробників, це повинно спростити і згладити процес вивчення архітектури CUDA
  2. Колективна між потоками пам'ять (shared memory) розміром в 16 Кб може бути використана під організований користувачем кеш з більш широкою смугою пропускання, ніж при вибірці зі звичайних текстур
  3. Більш ефективні транзакції між пам'яттю центрального процесора і відеопам'яттю
  4. Повна апаратна підтримка цілочисельних і побітових операцій
  5. Підтримка компіляції GPU коду засобами відкритого LLVM.

Підтримувані GPU і графічні прискорювачі[ред.ред. код]

Перелік пристроїв від виробника устаткування Nvidia із заявленою повною підтримкою технології CUDA приведений на офіційному сайті Nvidia: CUDA-Enabled GPU Products. Фактично ж, в даний час на ринку апаратних засобів для ПК підтримку технології CUDA забезпечують наступні периферійні пристрої:

Версія специфікації GPU Відеокарта
1.0 G80, G92, G92b, G94, G94b GeForce 8800GTX/Ultra, Tesla C/D/S870, FX4/5600, 360M, GT 420
1.1 G86, G84, G98, G96, G96b, G94, G94b, G92, G92b GeForce 8400GS/GT, 8600GT/GTS, 8800GT/GTS, 9400GT, 9600 GSO, 9600GT, 9800GTX/GX2, 9800GT, GTS 250, GT 120/30/40, FX 4/570, 3/580, 17/18/3700, 4700x2, 1xxM, 32/370M, 3/5/770M, 16/17/27/28/36/37/3800M, NVS420/50
1.2 GT218, GT216, GT215 GeForce 210, GT 220/40, FX380 LP, 1800M, 370/380M, NVS 2/3100M
1.3 GT200, GT200b GeForce GTX 260, GTX 275, GTX 280, GTX 285, GTX 295, Tesla C/M1060, S1070, Quadro CX, FX 3/4/5800
2.0 GF100, GF110 GeForce (GF100) GTX 465, GTX 470, GTX 480, Tesla C2050, C2070, S/M2050/70, Quadro Plex 7000, Quadro 4000, 5000, 6000, GeForce (GF110) GTX 560 TI 448, GTX570, GTX580, GTX590
2.1 GF104, GF114, GF116, GF108, GF106 GeForce 610M, GT 430, GT 440, GT 640, GTS 450, GTX 460, GTX 550 Ti, GTX 560, GTX 560 Ti, 500M, Quadro 600, 2000
3.0 GK104, GK106, GK107 GeForce GTX 690, GTX 680, GTX 670, GTX 660 Ti, GTX 660, GTX 650 Ti, GTX 650, GeForce GTX 680MX, GeForce GTX 680M, GeForce GTX 675MX, GeForce GTX 670MX, GTX 660M, GeForce GT 650M, GeForce GT 645M, GeForce GT 640M
3.5 GK110, GK208 GeForce GTX TITAN, GeForce GTX TITAN Black, GeForce GTX 780 Ti, GeForce GTX 780, GeForce GT 640 (GDDR5), GeForce GT 630 v2, Quadro K6000, Tesla K40, Tesla K20x, Tesla K20
5.0 GM107, GM108 GeForce GTX 750 Ti, GeForce GTX 750 , GeForce GTX 860M, GeForce GTX 850M, GeForce 840M, GeForce 830M

Ієрархічна модель CUDA[ред.ред. код]

Концепція CUDA відводить GPU роль масивно-паралельного співпроцесора. У літературі про CUDA основна система, до якої підключений GPU, коротко називається терміном хост (host). Аналогічно сам GPU по відношенню до хосту часто називається просто пристроєм (device). CUDA програма задіює як CPU, так і GPU. На CPU виконується послідовна частина коду і підготовчі стадії для GPU-обчислень. Паралельні ділянки коду можуть бути перенесені на GPU, де одночасно виконуватимуться великою кількістю ниток (потоків). Важливо відзначити ряд принципових відмінностей між звичайними потоками CPU і потоками GPU:

  1. Потік (thread) GPU надзвичайно легкий, його контекст мінімальний, регістри розподіленні заздалегідь;
  2. Для ефективного використання ресурсів GPU програмі необхідно задіяти тисячі окремих потоків, тоді як на багатоядерному CPU максимальна ефективність, зазвичай, досягається при числі потоків, рівному або в кілька разів більшому кількості ядер.

Робота потоків на GPU відповідає принципу SIMD. Проте є суттєва відмінність. Тільки потоки в межах однієї групи (для GPU архітектури Fermi - 32 потоки), так званого варпу (warp) виконуються фізично одночасно. Потоки різних варпів можуть знаходитися на різних стадіях виконання програми. Такий метод обробки даних позначається терміном SIMT (Single Instruction – Multiple Theads). Управління роботою варпів виконується на апаратному рівні. По ряду можливостей нових версій CUDA простежується тенденція до поступового перетворення GPU в самодостатній пристрій, повністю заміняючи звичайний CPU за рахунок реалізації деяких системних викликів (в термінології GPU системними викликами є, наприклад, malloc і free, реалізованих в CUDA 3.2) і додавання полегшеного енергоефективного CPU-ядра в GPU (архітектура Maxwell). Важливою перевагою CUDA є використання для програмування GPU мов високого рівня. В даний час існують компілятори C++ і Fortran. Ці мови розширюються невеликою множиною нових конструкцій: атрибути функцій і змінних, вбудовані змінні і типи даних, оператор запуску ядра. Розглянемо приклад CUDA-програми, що використовує GPU для поелементного складання двох одновимірних масивів:

Вказана мова не підтримується.

Необхідно вказати мову наступним чином: <source lang="html4strict">...</source>

Мови, що підтримуються:

c, cpp, bash, html4strict, text, java, latex, javascript, python, xml, csharp, php, css, asm, sql, pascal, matlab, html5, haskell, vb, lisp, ruby, ada, oracle11, dos, rsplus, fortran, d, bnf, ocaml, pcre, perl, vhdl, actionscript, lua, bibtex, go, bf, cobol, ini, delphi, arm, scheme, objc, prolog, actionscript3, mysql, qbasic, asp, algol68, groovy, erlang, abap, email, powershell, ecmascript, glsl, sas, apache, yaml, java5, vbnet, reg, cfm, fsharp, scala, applescript, gwbasic, clojure, pli, robots, tsql, whois, freebasic, verilog, llvm, visualfoxpro, sparql, tcl, plsql, coffeescript, scilab, dot, autoit, boo, mirc, lolcode, gnuplot, eiffel, j, teraterm, oorexx, diff, smalltalk, cmake, avisynth, perl6, xpp, typoscript, basic4gl, make, awk, e, gml, jquery, zxbasic, systemverilog, 6502acme, properties, oracle8, q, purebasic, pic16, ldif, rexx, unicon, urbi, modula3, mpasm, locobasic, progress, visualprolog, vala, octave, winbatch, oz, autohotkey, cadlisp, euphoria, pycon, oobas, povray, thinbasic, 68000devpac, mmix, modula2, cil, mxml, io, blitzbasic, parigp, oberon2


 
int sum_host( float * a, float * b, float * c, int n ) 
{ int nb = n * sizeof ( float ); float *aDev = NULL, *bDev = NULL, *cDev = NULL; 
// Виділити пам’ять на GPU. 
cudaError_t cuerr = cudaMalloc ( (void**)&aDev, nb ); if (cuerr != cudaSuccess) 
{ fprintf(stderr, "Cannot allocate GPU memory for aDev: %s\n" , cudaGetErrorString(cuerr));  return 1;
 } 
cuerr = cudaMalloc ( (void**)&bDev, nb );  if (cuerr != cudaSuccess)
 { 

fprintf(stderr, "Cannot allocate GPU memory for bDev: %s\n" , cudaGetErrorString(cuerr)); 
 return 1; 
}
 cuerr = cudaMalloc ( (void**)&cDev, nb );  
if (cuerr != cudaSuccess) 
' { fprintf(stderr, "Cannot allocate GPU memory for cDev: %s\n",
сudaGetErrorString(cuerr)); 
return 1; 
} 
// Завантажити конфігурацію запуска n потоків 
 dim3 threads = dim3(BL0CK_SIZE, 1);
 dim3 blocks = dim3(n / BLOCK_SIZE, 1); 
// Скопіювати вхідні дані з пам’яті CPU в пам’ять GPU. 
 cuerr = cudaMemcpy ( aDev, a, nb, cudaMemcpyHostToDevice );
  if (cuerr != cudaSuccess) { fprintf(stderr, "Cannot copy data from a to aDev: %s\n", cudaGetErrorString(cuerr)); 
 return 1;
 }
 cuerr = cudaMemcpy ( bDev, b, nb, cudaMemcpyHostToDevice ); 
 if (cuerr != cudaSuccess) 
{ fprintf(stderr, "Cannot copy data from b to bDev: %s\n", cudaGetErrorString(cuerr)); 
 return 1; } 
// Викликати ядро із заданою конфігурацією для обробки даних 
 sum_kernel<<<blocks, threads>>> (aDev, bDev, cDev); cuerr = cudaGetLastError() ;
  if (cuerr != cudaSuccess) { fprintf(stderr, "Cannot launch CUDA kernel: %s\n", cudaGetErrorString(cuerr)); 
return 1; } 
// Чекати завершення роботи ядра 
cuerr = cudaDeviceSynchronize(); 
if (cuerr != cudaSuccess) 
{ 
fprintf(stderr, "Cannot synchronize CUDA kernel: %s\n", cudaGetErrorString(cuerr)); 
 return 1;
 } 
// Скопіювати результати в пам’ять CPU
 cuerr = cudaMemcpy ( с, cDev, nb, cudaMemcpyDeviceToHost );
 if (cuerr != cudaSuccess) { fprintf(stderr, "Cannot copy data from cdev to c: %s\n", cudaGetErrorString(cuerr)); 
 return 1; 
 
// Звільнити виділену пам’ять GPU  
cudaFree ( aDev ); 
cudaFree ( bDev );
 cudaFree ( cDev ); 
return 0; 
} ">

Функція (або процедура у випадку Fortran) sum_kernel є ядром (атрибут _global_ або global) і виконуватиметься на GPU по одному незалежному потоку для кожного набору елементів a[i], b[i] і c[i]. Загальним прийомом програмування для CUDA є груповання багатьох потоків в блоки. На це є дві причини. По-перше, далеко не для кожного паралельного алгоритму існує ефективна реалізація на повністю незалежних потоках: результат одного потоку може залежати від результату деяких інших, вихідні дані потоку можуть частково збігатися з даними сусідніх. По-друге, розмір однієї вибірки даних з глобальної пам'яті набагато більша розміру дробового або цілочисельного типу, тобто одна вибірка може покрити запити групи з декількох потоків, що працюють з поряд йдучими в пам'яті елементами. У результаті груповання потоків вихідна задача розпадається на незалежні один від одного підзадачі (блоки потоків) з можливістю взаємодії потоків в рамках одного блоку і об'єднання запитів в пам'ять в рамках одного X 23 варпа (рис. 2.2). Розбиття потоків на варпи також відбувається окремо для кожного блоку. Об'єднання в блоки є вдалим компромісом між необхідністю забезпечити взаємодію потоків між собою і можливістю зробити відповідну апаратну логіку ефективною і дешевою.

Open64[ред.ред. код]

Призначений для трансляції host-коду (головного коду, що управляє) і device-коду (апаратного коду) (файлів з розширенням .cu) в об'єктні файли, придатні в процесі збирання кінцевої програми або бібліотеки в будь-якому середовищі програмування.

Див. також[ред.ред. код]

  • OpenCL - відкритий стандарт і API для апаратного прискорення обчислення на GPU та інших однорідних обчислювальних системах
  • OpenGL - графічне API, що починаючи з версії 4.3 підтримує обчислювальні шейдери
  • Direct3D - пропрієтарне API DirectX, що підтримує обчислювальні шейдери починаючи з версії DirectX 10
  • BrookGPU - одна з ранніх спроб створити мову програмування для забезпечення GPGPU
  • Close to Metal - ранній пропрієтарний низькорівневий API для обчислення на GPU для графічних адаптерів ATI/AMD
  • Векторизація

Посилання[ред.ред. код]