Ц ++

ГПУ програмирање са Ц ++

ГПУ програмирање са Ц ++

Преглед

У овом водичу ћемо истражити снагу ГПУ програмирања са Ц-ом++. Програмери могу очекивати невероватне перформансе са Ц ++-ом, а приступ феноменалној снази ГПУ-а језиком ниског нивоа може дати неке од најбржих тренутно доступних рачунања.

Захтеви

Иако било која машина способна за покретање савремене верзије Линука може подржати Ц ++ компајлер, за праћење ове вежбе биће вам потребан ГПУ заснован на НВИДИА. Ако немате ГПУ, можете да завртите инстанцу засновану на ГПУ-у у Амазон Веб Сервицес-у или другом добављачу услуга у облаку по вашем избору.

Ако одаберете физичку машину, побрините се да имате инсталиране власничке управљачке програме НВИДИА. Упутства за ово можете пронаћи овде: хттпс: // линукхинт.цом / инсталл-нвидиа-дриверс-линук /

Поред управљачког програма, биће вам потребан ЦУДА алат. У овом примеру ћемо користити Убунту 16.04 ЛТС, али постоје доступна преузимања за већину главних дистрибуција на следећем УРЛ-у: хттпс: // програмер.нвидиа.цом / цуда-довнлоадс

За Убунту бисте изабрали .преузимање на основу деб-а. Преузета датотека неће имати .деб проширење по дефаулту, па препоручујем да га преименујете у а .деб на крају. Затим можете инсталирати са:

судо дпкг -и назив пакета.деб

Вероватно ће вам бити затражено да инсталирате ГПГ кључ, а ако јесте, следите упутства да бисте то урадили.

Када то учините, ажурирајте своја спремишта:

судо апт-гет упдате
судо апт-гет инсталл цуда -и

Када завршите, препоручујем поновно покретање како бисте били сигурни да је све правилно учитано.

Предности развоја ГПУ-а

ЦПУ обрађују много различитих улаза и излаза и садрже велики асортиман функција не само да се баве широким асортиманом програмских потреба већ и за управљање различитим хардверским конфигурацијама. Такође се баве меморијом, кеширањем, системском магистралом, сегментирањем и ИО функционалношћу, што их чини дизалицом свих трговина.

ГПУ-ови су супротно - садрже много појединачних процесора који су усредсређени на врло једноставне математичке функције. Због тога обрађују задатке много пута брже од ЦПУ-а. Специјализацијом за скаларне функције (функција која узима један или више улаза, али враћа само један излаз), постижу екстремне перформансе по цену екстремне специјализације.

Пример кода

У примеру кода додајемо векторе заједно. Додао сам ЦПУ и ГПУ верзију кода за поређење брзине.
гпу-пример.цпп садржај испод:

#инцлуде "цуда_рунтиме.х "
#инцлуде
#инцлуде
#инцлуде
#инцлуде
#инцлуде
типедеф стд :: цхроно :: хигх_ресолутион_цлоцк Цлоцк;
#дефине ИТЕР 65535
// ЦПУ верзија функције векторског додавања
воид вецтор_адд_цпу (инт * а, инт * б, инт * ц, инт н)
инт и;
// Векторским елементима додајте елементе а и б
за (и = 0; и < n; ++i)
ц [и] = а [и] + б [и];


// ГПУ верзија функције векторског додавања
__глобал__ воид вецтор_адд_гпу (инт * гпу_а, инт * гпу_б, инт * гпу_ц, инт н)
инт и = тхреадИдк.Икс;
// Не треба за петљу јер је ЦУДА време извршавања
// ће пребацити ово ИТЕР пута
гпу_ц [и] = гпу_а [и] + гпу_б [и];

инт маин ()
инт * а, * б, * ц;
инт * гпу_а, * гпу_б, * гпу_ц;
а = (инт *) маллоц (ИТЕР * величина (инт));
б = (инт *) маллоц (ИТЕР * величина (инт));
ц = (инт *) маллоц (ИТЕР * величина (инт));
// Потребне су нам променљиве доступне ГПУ-у,
// па цудаМаллоцМанагед пружа ове
цудаМаллоцМанагед (& гпу_а, ИТЕР * сизеоф (инт));
цудаМаллоцМанагед (& гпу_б, ИТЕР * сизеоф (инт));
цудаМаллоцМанагед (& гпу_ц, ИТЕР * сизеоф (инт));
за (инт и = 0; и < ITER; ++i)
а [и] = и;
б [и] = и;
ц [и] = и;

// Позовите ЦПУ функцију и мерите време
ауто цпу_старт = Цлоцк :: нов ();
вецтор_адд_цпу (а, б, ц, ИТЕР);
ауто цпу_енд = Цлоцк :: нов ();
стд :: цоут << "vector_add_cpu: "
<< std::chrono::duration_cast(цпу_енд - цпу_старт).цоунт ()
<< " nanoseconds.\n";
// Позовите ГПУ функцију и мерите време
// Троструки угаони носачи су ЦУДА рунтиме продужење које омогућава
// параметри позива ЦУДА кернела који се прослеђују.
// У овом примеру преносимо један блок нити ИТЕР нитима.
ауто гпу_старт = Цлоцк :: нов ();
вецтор_адд_гпу <<<1, ITER>>> (гпу_а, гпу_б, гпу_ц, ИТЕР);
цудаДевицеСинцхронизе ();
ауто гпу_енд = Цлоцк :: нов ();
стд :: цоут << "vector_add_gpu: "
<< std::chrono::duration_cast(гпу_енд - гпу_старт).цоунт ()
<< " nanoseconds.\n";
// Ослободите расподјелу меморије засноване на ГПУ функцији
цудаФрее (а);
цудаФрее (б);
цудаФрее (ц);
// Ослободите расподјелу меморије засноване на ЦПУ функцији
бесплатно (а);
бесплатно (б);
бесплатно (ц);
ретурн 0;

Макефиле садржај испод:

ИНЦ = -И / уср / лоцал / цуда / инцлуде
НВЦЦ = / уср / лоцал / цуда / бин / нвцц
НВЦЦ_ОПТ = -стд = ц ++ 11
све:
$ (НВЦЦ) $ (НВЦЦ_ОПТ) гпу-пример.цпп -о гпу-пример
чист:
-рм -ф гпу-пример

Да бисте покренули пример, компајлирајте га:

направити

Затим покрените програм:

./ гпу-пример

Као што видите, верзија процесора (вецтор_адд_цпу) ради знатно спорије од верзије ГПУ (вецтор_адд_гпу).

Ако није, можда ћете морати да прилагодите дефиницију ИТЕР у примеру гпу.цу на већи број. То је због тога што је време подешавања ГПУ-а дуже од неких мањих петљи које захтевају ЦПУ. Открио сам да 65535 добро ради на мојој машини, али ваша километража може варирати. Међутим, када очистите овај праг, ГПУ је драматично бржи од ЦПУ-а.

Закључак

Надам се да сте пуно научили из нашег увођења у ГПУ програмирање са Ц-ом++. Горњи пример не постиже много, али демонстрирани концепти пружају оквир који можете користити за укључивање својих идеја како бисте ослободили снагу свог ГПУ-а.

Најбоље игре командне линије за Линук
Командна линија није само ваш највећи савезник када користите Линук - она ​​такође може бити извор забаве јер је можете користити за играње многих заб...
Најбоље апликације за мапирање гамепада за Линук
Ако волите да играте игре на Линуку са гамепадом уместо са типичним системом за унос тастатуре и миша, за вас постоје неке корисне апликације. Многе и...
Корисни алати за Линук играче
Ако волите да играте игре на Линуку, велика је вероватноћа да сте можда користили апликације и услужне програме попут Вине, Лутрис и ОБС Студио за поб...