10.07.2015 Views

NVIDIA CUDA — неграфические вычисления на графических ...

NVIDIA CUDA — неграфические вычисления на графических ...

NVIDIA CUDA — неграфические вычисления на графических ...

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

<strong>NVIDIA</strong> <strong>CUDA</strong> <strong>—</strong> <strong>неграфические</strong><strong>вычисления</strong> <strong>на</strong> <strong>графических</strong> процессорахВведениеУстройства для превращения персо<strong>на</strong>льных компьютеров в маленькие суперкомпьютерыизвестны довольно давно. Ещё в 80-х годах прошлого века <strong>на</strong> рынке предлагались так<strong>на</strong>зываемые транспьютеры, которые вставлялись в распространенные тогда слотырасширения ISA. Первое время их производительность в соответствующих задачахвпечатляла, но затем рост быстродействия универсальных процессоров ускорился, ониусилили свои позиции в параллельных <strong>вычисления</strong>х, и смысла в транспьютерах неосталось. Хотя подобные устройства существуют и сейчас <strong>—</strong> это разнообразныеспециализированные ускорители. Но зачастую сфера их применения узка и особогораспространения такие ускорители не получили.Но в последнее время эстафета параллельных вычислений перешла к массовому рынку,так или и<strong>на</strong>че связанному с трёхмерными играми. Универсальные устройства смногоядерными процессорами для параллельных векторных вычислений, используемых в3D-графике, достигают высокой пиковой производительности, которая универсальнымпроцессорам не под силу. Конечно, максималь<strong>на</strong>я скорость достигается лишь в рядеудобных задач и имеет некоторые ограничения, но такие устройства уже <strong>на</strong>чали довольношироко применять в сферах, для которых они из<strong>на</strong>чально и не пред<strong>на</strong>з<strong>на</strong>чались.Отличным примером такого параллельного процессора является процессор Cell,разработанный альянсом Sony-Toshiba-IBM и применяемый в игровой приставке SonyPlayStation 3, а также и все современные видеокарты от лидеров рынка <strong>—</strong> компаний<strong>NVIDIA</strong> и AMD.Cell мы сегодня трогать не будем, хоть он и появился раньше и является универсальнымпроцессором с дополнительными векторными возможностями, речь сегодня не о нём. Для3D видеоускорителей ещё несколько лет <strong>на</strong>зад появились первые технологиине<strong>графических</strong> расчётов общего <strong>на</strong>з<strong>на</strong>чения GPGPU (General-Purpose computation onGPUs). Ведь современные видеочипы содержат сотни математических исполнительныхблоков, и эта мощь может использоваться для з<strong>на</strong>чительного ускорения множествавычислительно интенсивных приложений. И нынешние поколения GPU обладаютдостаточно гибкой архитектурой, что вместе с высокоуровневыми языками


программирования и программно-аппаратными архитектурами, подобнымирассматриваемой в этой статье, раскрывает эти возможности и делает их з<strong>на</strong>чительноболее доступными.На создание GPCPU разработчиков побудило появление достаточно быстрых и гибкихшейдерных программ, которые способны исполнять современные видеочипы.Разработчики задумали сделать так, чтобы GPU рассчитывали не только изображение в3D приложениях, но и применялись в других параллельных расчётах. В GPGPU для этогоиспользовались графические API: OpenGL и Direct3D, когда данные к видеочипупередавались в виде текстур, а расчётные программы загружались в виде шейдеров.Недостатками такого метода является сравнительно высокая сложностьпрограммирования, низкая скорость обме<strong>на</strong> данными между CPU и GPU и другиеограничения, о которых мы поговорим далее.Вычисления <strong>на</strong> GPU развивались и развиваются очень быстро. И в дальнейшем, дваосновных производителя видеочипов, <strong>NVIDIA</strong> и AMD, разработали и анонсировалисоответствующие платформы под <strong>на</strong>званием <strong>CUDA</strong> (Compute Unified Device Architecture)и CTM (Close To Metal или AMD Stream Computing), соответственно. В отличие отпредыдущих моделей программирования GPU, эти были выполнены с учётом прямогодоступа к аппаратным возможностям видеокарт. Платформы не совместимы между собой,<strong>CUDA</strong> <strong>—</strong> это расширение языка программирования C, а CTM <strong>—</strong> виртуаль<strong>на</strong>я маши<strong>на</strong>,исполняющая ассемблерный код. Зато обе платформы ликвидировали некоторые изважных ограничений предыдущих моделей GPGPU, использующих традиционныйграфический конвейер и соответствующие интерфейсы Direct3D или OpenGL.Конечно же, открытые стандарты, использующие OpenGL, кажутся <strong>на</strong>иболеепортируемыми и универсальными, они позволяют использовать один и тот же код длявидеочипов разных производителей. Но у таких методов есть масса недостатков, ониз<strong>на</strong>чительно менее гибкие и не такие удобные в использовании. Кроме того, они не даютиспользовать специфические возможности определённых видеокарт, такие, как быстраяразделяемая (общая) память, присутствующая в современных вычислительныхпроцессорах.Именно поэтому компания <strong>NVIDIA</strong> выпустила платформу <strong>CUDA</strong> <strong>—</strong> C-подобный языкпрограммирования со своим компилятором и библиотеками для вычислений <strong>на</strong> GPU.Конечно же, <strong>на</strong>писание оптимального кода для видеочипов совсем не такое простое и этазадача нуждается в длительной ручной работе, но <strong>CUDA</strong> как раз и раскрывает всевозможности и даёт программисту больший контроль <strong>на</strong>д аппаратными возможностямиGPU. Важно, что поддержка <strong>NVIDIA</strong> <strong>CUDA</strong> есть у чипов G8x, G9x и GT2xx,применяемых в видеокартах GeForce серий 8, 9 и 200, которые очень широкораспространены. В <strong>на</strong>стоящее время выпуще<strong>на</strong> фи<strong>на</strong>ль<strong>на</strong>я версия <strong>CUDA</strong> 2.0, в которойпоявились некоторые новые возможности, <strong>на</strong>пример, поддержка расчётов с двойнойточностью. <strong>CUDA</strong> доступ<strong>на</strong> <strong>на</strong> 32-битных и 64-битных операционных системах Linux,Windows и MacOS X.Разница между CPU и GPU в параллельных расчётахРост частот универсальных процессоров упёрся в физические ограничения и высокоеэнергопотребление, и увеличение их производительности всё чаще происходит за счётразмещения нескольких ядер в одном чипе. Продаваемые сейчас процессоры содержатлишь до четырёх ядер (дальнейший рост не будет быстрым) и они пред<strong>на</strong>з<strong>на</strong>чены дляобычных приложений, используют MIMD <strong>—</strong> множественный поток команд и данных.


Каждое ядро работает отдельно от остальных, исполняя разные инструкции для разныхпроцессов.Специализированные векторные возможности (SSE2 и SSE3) для четырехкомпонентных(оди<strong>на</strong>р<strong>на</strong>я точность вычислений с плавающей точкой) и двухкомпонентных (двой<strong>на</strong>яточность) векторов появились в универсальных процессорах из-за возросших требований<strong>графических</strong> приложений, в первую очередь. Именно поэтому для определённых задачприменение GPU выгоднее, ведь они из<strong>на</strong>чально сделаны для них.Например, в видеочипах <strong>NVIDIA</strong> основной блок <strong>—</strong> это мультипроцессор с восемьюдесятьюядрами и сотнями ALU в целом, несколькими тысячами регистров и небольшимколичеством разделяемой общей памяти. Кроме того, видеокарта содержит быструюглобальную память с доступом к ней всех мультипроцессоров, локальную память вкаждом мультипроцессоре, а также специальную память для констант.Самое главное <strong>—</strong> эти несколько ядер мультипроцессора в GPU являются SIMD(одиночный поток команд, множество потоков данных) ядрами. И эти ядра исполняютодни и те же инструкции одновременно, такой стиль программирования являетсяобычным для <strong>графических</strong> алгоритмов и многих <strong>на</strong>учных задач, но требуетспецифического программирования. Зато такой подход позволяет увеличить количествоисполнительных блоков за счёт их упрощения.Итак, перечислим основные различия между архитектурами CPU и GPU. Ядра CPUсозданы для исполнения одного потока последовательных инструкций с максимальнойпроизводительностью, а GPU проектируются для быстрого исполнения большого числапараллельно выполняемых потоков инструкций. Универсальные процессорыоптимизированы для достижения высокой производительности единственного потокакоманд, обрабатывающего и целые числа и числа с плавающей точкой. При этом доступ кпамяти случайный.Разработчики CPU стараются добиться выполнения как можно большего числаинструкций параллельно, для увеличения производительности. Для этого, <strong>на</strong>чи<strong>на</strong>я спроцессоров Intel Pentium, появилось суперскалярное выполнение, обеспечивающеевыполнение двух инструкций за такт, а Pentium Pro отличился внеочереднымвыполнением инструкций. Но у параллельного выполнения последовательного потокаинструкций есть определённые базовые ограничения и увеличением количестваисполнительных блоков кратного увеличения скорости не добиться.У видеочипов работа простая и распараллелен<strong>на</strong>я из<strong>на</strong>чально. Видеочип принимает <strong>на</strong>входе группу полигонов, проводит все необходимые операции, и <strong>на</strong> выходе выдаётпиксели. Обработка полигонов и пикселей независима, их можно обрабатыватьпараллельно, отдельно друг от друга. Поэтому, из-за из<strong>на</strong>чально параллельнойорганизации работы в GPU используется большое количество исполнительных блоков,которые легко загрузить, в отличие от последовательного потока инструкций для CPU.Кроме того, современные GPU также могут исполнять больше одной инструкции за такт(dual issue). Так, архитектура Tesla в некоторых условиях запускает <strong>на</strong> исполнениеоперации MAD+MUL или MAD+SFU одновременно.GPU отличается от CPU ещё и по принципам доступа к памяти. В GPU он связанный илегко предсказуемый <strong>—</strong> если из памяти читается тексель текстуры, то через некотороевремя придёт время и для соседних текселей. Да и при записи то же <strong>—</strong> пиксельзаписывается во фреймбуфер, и через несколько тактов будет записываться


расположенный рядом с ним. Поэтому организация памяти отличается от той, чтоиспользуется в CPU. И видеочипу, в отличие от универсальных процессоров, просто ненуж<strong>на</strong> кэш-память большого размера, а для текстур требуются лишь несколько (до 128-256 в нынешних GPU) килобайт.Да и сама по себе работа с памятью у GPU и CPU несколько отличается. Так, не всецентральные процессоры имеют встроенные контроллеры памяти, а у всех GPU обычноесть по несколько контроллеров, вплоть до восьми 64-битных ка<strong>на</strong>лов в чипе <strong>NVIDIA</strong>GT200. Кроме того, <strong>на</strong> видеокартах применяется более быстрая память, и в результатевидеочипам доступ<strong>на</strong> в разы большая пропуск<strong>на</strong>я способность памяти, что также весьмаважно для параллельных расчётов, оперирующих с огромными потоками данных.В универсальных процессорах большие количества транзисторов и площадь чипа идут <strong>на</strong>буферы команд, аппаратное предсказание ветвления и огромные объёмы <strong>на</strong>чиповой кэшпамяти.Все эти аппаратные блоки нужны для ускорения исполнения немногочисленныхпотоков команд. Видеочипы тратят транзисторы <strong>на</strong> массивы исполнительных блоков,управляющие потоками блоки, разделяемую память небольшого объёма и контроллерыпамяти <strong>на</strong> несколько ка<strong>на</strong>лов. Вышеперечисленное не ускоряет выполнение отдельныхпотоков, оно позволяет чипу обрабатывать нескольких тысяч потоков, одновременноисполняющихся чипом и требующих высокой пропускной способности памяти.Про отличия в кэшировании. Универсальные центральные процессоры используют кэшпамятьдля увеличения производительности за счёт снижения задержек доступа к памяти,а GPU используют кэш или общую память для увеличения полосы пропускания. CPUснижают задержки доступа к памяти при помощи кэш-памяти большого размера, а такжепредсказания ветвлений кода. Эти аппаратные части занимают большую часть площадичипа и потребляют много энергии. Видеочипы обходят проблему задержек доступа кпамяти при помощи одновременного исполнения тысяч потоков <strong>—</strong> в то время, когда одиниз потоков ожидает данных из памяти, видеочип может выполнять <strong>вычисления</strong> другогопотока без ожидания и задержек.Есть множество различий и в поддержке многопоточности. CPU исполняет 1-2 потокавычислений <strong>на</strong> одно процессорное ядро, а видеочипы могут поддерживать до 1024потоков <strong>на</strong> каждый мультипроцессор, которых в чипе несколько штук. И еслипереключение с одного потока <strong>на</strong> другой для CPU стоит сотни тактов, то GPUпереключает несколько потоков за один такт.Кроме того, центральные процессоры используют SIMD (од<strong>на</strong> инструкция выполняется<strong>на</strong>д многочисленными данными) блоки для векторных вычислений, а видеочипыприменяют SIMT (од<strong>на</strong> инструкция и несколько потоков) для скалярной обработкипотоков. SIMT не требует, чтобы разработчик преобразовывал данные в векторы, идопускает произвольные ветвления в потоках.Вкратце можно сказать, что в отличие от современных универсальных CPU, видеочипыпред<strong>на</strong>з<strong>на</strong>чены для параллельных вычислений с большим количеством арифметическихопераций. И з<strong>на</strong>чительно большее число транзисторов GPU работает по прямому<strong>на</strong>з<strong>на</strong>чению <strong>—</strong> обработке массивов данных, а не управляет исполнением (flow control)немногочисленных последовательных вычислительных потоков. Это схема того, сколькоместа в CPU и GPU занимает разнообраз<strong>на</strong>я логика:


В итоге, основой для эффективного использования мощи GPU в <strong>на</strong>учных и иныхне<strong>графических</strong> расчётах является распараллеливание алгоритмов <strong>на</strong> сотниисполнительных блоков, имеющихся в видеочипах. К примеру, множество приложений помолекулярному моделированию отлично приспособлено для расчётов <strong>на</strong> видеочипах, онитребуют больших вычислительных мощностей и поэтому удобны для параллельныхвычислений. А использование нескольких GPU даёт ещё больше вычислительныхмощностей для решения подобных задач.Выполнение расчётов <strong>на</strong> GPU показывает отличные результаты в алгоритмах,использующих параллельную обработку данных. То есть, когда одну и ту жепоследовательность математических операций применяют к большому объёму данных.При этом лучшие результаты достигаются, если отношение числа арифметическихинструкций к числу обращений к памяти достаточно велико. Это предъявляет меньшиетребования к управлению исполнением (flow control), а высокая плотность математики ибольшой объём данных отменяет необходимость в больших кэшах, как <strong>на</strong> CPU.В результате всех описанных выше отличий, теоретическая производительностьвидеочипов з<strong>на</strong>чительно превосходит производительность CPU. Компания <strong>NVIDIA</strong>приводит такой график роста производительности CPU и GPU за последние нескольколет:Естественно, эти данные не без доли лукавства. Ведь <strong>на</strong> CPU гораздо проще <strong>на</strong> практикедостичь теоретических цифр, да и цифры приведены для оди<strong>на</strong>рной точности в случаеGPU, и для двойной <strong>—</strong> в случае CPU. В любом случае, для части параллельных задач


оди<strong>на</strong>рной точности хватает, а разница в скорости между универсальными играфическими процессорами весьма велика, и поэтому овчинка стоит выделки.Первые попытки применения расчётов <strong>на</strong> GPUВидеочипы в параллельных математических расчётах пытались использовать довольнодавно. Самые первые попытки такого применения были крайне примитивными иограничивались использованием некоторых аппаратных функций, таких, как растеризацияи Z-буферизация. Но в нынешнем веке, с появлением шейдеров, <strong>на</strong>чали ускорять<strong>вычисления</strong> матриц. В 2003 году <strong>на</strong> SIGGRAPH отдель<strong>на</strong>я секция была выделе<strong>на</strong> под<strong>вычисления</strong> <strong>на</strong> GPU, и о<strong>на</strong> получила <strong>на</strong>звание GPGPU (General-Purpose computation onGPU) <strong>—</strong> универсальные <strong>вычисления</strong> <strong>на</strong> GPU).Наиболее известен BrookGPU <strong>—</strong> компилятор потокового языка программирования Brook,созданный для выполнения не<strong>графических</strong> вычислений <strong>на</strong> GPU. До его появленияразработчики, использующие возможности видеочипов для вычислений, выбирали одиниз двух распространённых API: Direct3D или OpenGL. Это серьёзно ограничивалоприменение GPU, ведь в 3D графике используются шейдеры и текстуры, о которыхспециалисты по параллельному программированию з<strong>на</strong>ть не обязаны, они используютпотоки и ядра. Brook смог помочь в облегчении их задачи. Эти потоковые расширения кязыку C, разработанные в Стэндфордском университете, скрывали от программистовтрёхмерный API, и представляли видеочип в виде параллельного сопроцессора.Компилятор обрабатывал файл .br с кодом C++ и расширениями, производя код,привязанный к библиотеке с поддержкой DirectX, OpenGL или x86.Естественно, у Brook было множество недостатков, <strong>на</strong> которых мы оста<strong>на</strong>вливались, и окоторых ещё подробнее поговорим далее. Но даже просто его появление вызвалоз<strong>на</strong>чительный прилив внимания тех же <strong>NVIDIA</strong> и ATI к инициативе вычислений <strong>на</strong> GPU,так как развитие этих возможностей серьёзно изменило рынок в дальнейшем, открывцелый новый его сектор <strong>—</strong> параллельные вычислители <strong>на</strong> основе видеочипов.В дальнейшем, некоторые исследователи из проекта Brook влились в командуразработчиков <strong>NVIDIA</strong>, чтобы представить программно-аппаратную стратегиюпараллельных вычислений, открыв новую долю рынка. И главным преимуществом этойинициативы <strong>NVIDIA</strong> стало то, что разработчики отлично з<strong>на</strong>ют все возможности своихGPU до мелочей, и в использовании графического API нет необходимости, а работать саппаратным обеспечением можно <strong>на</strong>прямую при помощи драйвера. Результатом усилийэтой команды стала <strong>NVIDIA</strong> <strong>CUDA</strong> (Compute Unified Device Architecture) <strong>—</strong> новаяпрограммно-аппарат<strong>на</strong>я архитектура для параллельных вычислений <strong>на</strong> <strong>NVIDIA</strong> GPU,которой посвяще<strong>на</strong> эта статья.Области применения параллельных расчётов <strong>на</strong> GPUЧтобы понять, какие преимущества приносит перенос расчётов <strong>на</strong> видеочипы, приведёмусреднённые цифры, полученные исследователями по всему миру. В среднем, припереносе вычислений <strong>на</strong> GPU, во многих задачах достигается ускорение в 5-30 раз, посравнению с быстрыми универсальными процессорами. Самые большие цифры (порядка100-кратного ускорения и даже более!) достигаются <strong>на</strong> коде, который не очень хорошоподходит для расчётов при помощи блоков SSE, но вполне удобен для GPU.Это лишь некоторые примеры ускорений синтетического кода <strong>на</strong> GPU против SSEвекторизованногокода <strong>на</strong> CPU (по данным <strong>NVIDIA</strong>):


Флуоресцент<strong>на</strong>я микроскопия: 12x; Молекуляр<strong>на</strong>я ди<strong>на</strong>мика (non-bonded force calc): 8-16x; Электростатика (прямое и многоуровневое суммирование Куло<strong>на</strong>): 40-120x и 7x.А это табличка, которую очень любит <strong>NVIDIA</strong>, показывая её <strong>на</strong> всех презентациях, <strong>на</strong>которой мы подробнее остановимся во второй части статьи, посвящённой конкретнымпримерам практических применений <strong>CUDA</strong> вычислений:Как видите, цифры весьма привлекательные, особенно впечатляют 100-150-кратныеприросты. В следующей статье, посвящённой <strong>CUDA</strong>, мы подробно разберём некоторые изэтих цифр. А сейчас перечислим основные приложения, в которых сейчас применяются<strong>вычисления</strong> <strong>на</strong> GPU: а<strong>на</strong>лиз и обработка изображений и сиг<strong>на</strong>лов, симуляция физики,вычислитель<strong>на</strong>я математика, вычислитель<strong>на</strong>я биология, фи<strong>на</strong>нсовые расчёты, базыданных, ди<strong>на</strong>мика газов и жидкостей, криптография, адаптив<strong>на</strong>я лучевая терапия,астрономия, обработка звука, биоинформатика, биологические симуляции, компьютерноезрение, а<strong>на</strong>лиз данных (data mining), цифровое кино и телевидение, электромагнитныесимуляции, геоинформационные системы, военные применения, горное планирование,молекуляр<strong>на</strong>я ди<strong>на</strong>мика, магнитно-резо<strong>на</strong>нс<strong>на</strong>я томография (MRI), нейросети,океанографические исследования, физика частиц, симуляция свёртывания молекул белка,квантовая химия, трассировка лучей, визуализация, радары, гидроди<strong>на</strong>мическоемоделирование (reservoir simulation), искусственный интеллект, а<strong>на</strong>лиз спутниковыхданных, сейсмическая разведка, хирургия, ультразвук, видеоконференции.


Подробности о многих применениях можно <strong>на</strong>йти <strong>на</strong> сайте компании <strong>NVIDIA</strong> в разделепо технологии <strong>CUDA</strong>. Как видите, список довольно большой, но и это ещё не всё! Егоможно продолжать, и <strong>на</strong>верняка можно предположить, что в будущем будут <strong>на</strong>йдены идругие области применения параллельных расчётов <strong>на</strong> видеочипах, о которых мы пока недогадываемся.Возможности <strong>NVIDIA</strong> <strong>CUDA</strong>Технология <strong>CUDA</strong> <strong>—</strong> это программно-аппарат<strong>на</strong>я вычислитель<strong>на</strong>я архитектура <strong>NVIDIA</strong>,основан<strong>на</strong>я <strong>на</strong> расширении языка Си, которая даёт возможность организации доступа к<strong>на</strong>бору инструкций графического ускорителя и управления его памятью при организациипараллельных вычислений. <strong>CUDA</strong> помогает реализовывать алгоритмы, выполнимые <strong>на</strong><strong>графических</strong> процессорах видеоускорителей GeForce восьмого поколения и старше (серииGeForce 8, GeForce 9, GeForce 200), а также Quadro и Tesla.Хотя трудоёмкость программирования GPU при помощи <strong>CUDA</strong> довольно велика, о<strong>на</strong>ниже, чем с ранними GPGPU решениями. Такие программы требуют разбиенияприложения между несколькими мультипроцессорами подобно MPI программированию,но без разделения данных, которые хранятся в общей видеопамяти. И так как <strong>CUDA</strong>программирование для каждого мультипроцессора подобно OpenMP программированию,оно требует хорошего понимания организации памяти. Но, конечно же, сложностьразработки и переноса <strong>на</strong> <strong>CUDA</strong> сильно зависит от приложения.Набор для разработчиков содержит множество примеров кода и хорошо документирован.Процесс обучения потребует около двух-четырёх недель для тех, кто уже з<strong>на</strong>ком сOpenMP и MPI. В основе API лежит расширенный язык Си, а для трансляции кода с этогоязыка в состав <strong>CUDA</strong> SDK входит компилятор командной строки nvcc, созданный <strong>на</strong>основе открытого компилятора Open64.Перечислим основные характеристики <strong>CUDA</strong>:унифицированное программно-аппаратное решение для параллельных вычислений<strong>на</strong> видеочипах <strong>NVIDIA</strong>;большой <strong>на</strong>бор поддерживаемых решений, от мобильных до мультичиповыхстандартный язык программирования Си;стандартные библиотеки численного а<strong>на</strong>лиза FFT (быстрое преобразование Фурье)и BLAS (линей<strong>на</strong>я алгебра);оптимизированный обмен данными между CPU и GPU;взаимодействие с графическими API OpenGL и DirectX;поддержка 32- и 64-битных операционных систем: Windows XP, Windows Vista,Linux и MacOS X;возможность разработки <strong>на</strong> низком уровне.Касательно поддержки операционных систем нужно добавить, что официальноподдерживаются все основные дистрибутивы Linux (Red Hat Enterprise Linux 3.x/4.x/5.x,SUSE Linux 10.x), но, судя по данным энтузиастов, <strong>CUDA</strong> прекрасно работает и <strong>на</strong> другихсборках: Fedora Core, Ubuntu, Gentoo и др.Среда разработки <strong>CUDA</strong> (<strong>CUDA</strong> Toolkit) включает:компилятор nvcc;библиотеки FFT и BLAS;


профилировщик;отладчик gdb для GPU;<strong>CUDA</strong> runtime драйвер в комплекте стандартных драйверов <strong>NVIDIA</strong>руководство по программированию;<strong>CUDA</strong> Developer SDK (исходный код, утилиты и документация).В примерах исходного кода: параллель<strong>на</strong>я битон<strong>на</strong>я сортировка (bitonic sort),транспонирование матриц, параллельное префиксное суммирование больших массивов,свёртка изображений, дискретное вейвлет-преобразование, пример взаимодействия сOpenGL и Direct3D, использование библиотек CUBLAS и CUFFT, вычисление ценыопцио<strong>на</strong> (формула Блэка-Шоулза, биномиаль<strong>на</strong>я модель, метод Монте-Карло),параллельный генератор случайных чисел Mersenne Twister, вычисление гистограммыбольшого массива, шумоподавление, фильтр Собеля (<strong>на</strong>хождение границ).Преимущества и ограничения <strong>CUDA</strong>С точки зрения программиста, графический конвейер является <strong>на</strong>бором стадий обработки.Блок геометрии генерирует треугольники, а блок растеризации <strong>—</strong> пиксели, отображаемые<strong>на</strong> мониторе. Традицион<strong>на</strong>я модель программирования GPGPU выглядит следующимобразом:Чтобы перенести <strong>вычисления</strong> <strong>на</strong> GPU в рамках такой модели, нужен специальный подход.Даже поэлементное сложение двух векторов потребует отрисовки фигуры <strong>на</strong> экране иливо внеэкранный буфер. Фигура растеризуется, цвет каждого пикселя вычисляется позаданной программе (пиксельному шейдеру). Программа считывает входные данные изтекстур для каждого пикселя, складывает их и записывает в выходной буфер. И все этимногочисленные операции нужны для того, что в обычном языке программированиязаписывается одним оператором!Поэтому, применение GPGPU для вычислений общего <strong>на</strong>з<strong>на</strong>чения имеет ограничение ввиде слишком большой сложности обучения разработчиков. Да и других ограниченийдостаточно, ведь пиксельный шейдер <strong>—</strong> это всего лишь формула зависимости итоговогоцвета пикселя от его коорди<strong>на</strong>ты, а язык пиксельных шейдеров <strong>—</strong> язык записи этихформул с Си-подобным синтаксисом. Ранние методы GPGPU являются хитрым трюком,


позволяющим использовать мощность GPU, но без всякого удобства. Данные тампредставлены изображениями (текстурами), а алгоритм <strong>—</strong> процессом растеризации.Нужно особо отметить и весьма специфичную модель памяти и исполнения.Программно-аппарат<strong>на</strong>я архитектура для вычислений <strong>на</strong> GPU компании <strong>NVIDIA</strong>отличается от предыдущих моделей GPGPU тем, что позволяет писать программы дляGPU <strong>на</strong> <strong>на</strong>стоящем языке Си со стандартным синтаксисом, указателями инеобходимостью в минимуме расширений для доступа к вычислительным ресурсамвидеочипов. <strong>CUDA</strong> не зависит от <strong>графических</strong> API, и обладает некоторымиособенностями, пред<strong>на</strong>з<strong>на</strong>ченными специально для вычислений общего <strong>на</strong>з<strong>на</strong>чения.Преимущества <strong>CUDA</strong> перед традиционным подходом к GPGPU <strong>вычисления</strong>м: интерфейс программирования приложений <strong>CUDA</strong> основан <strong>на</strong> стандартном языкепрограммирования Си с расширениями, что упрощает процесс изучения ивнедрения архитектуры <strong>CUDA</strong>; <strong>CUDA</strong> обеспечивает доступ к разделяемой между потоками памяти размером в 16Кб <strong>на</strong> мультипроцессор, которая может быть использова<strong>на</strong> для организации кэша сширокой полосой пропускания, по сравнению с текстурными выборками; более эффектив<strong>на</strong>я передача данных между системной и видеопамятью отсутствие необходимости в <strong>графических</strong> API с избыточностью и <strong>на</strong>кладнымирасходами; линей<strong>на</strong>я адресация памяти, и gather и scatter, возможность записи попроизвольным адресам; аппарат<strong>на</strong>я поддержка целочисленных и битовых операций.Основные ограничения <strong>CUDA</strong>:отсутствие поддержки рекурсии для выполняемых функций;минималь<strong>на</strong>я шири<strong>на</strong> блока в 32 потока;закрытая архитектура <strong>CUDA</strong>, при<strong>на</strong>длежащая <strong>NVIDIA</strong>.Слабыми местами программирования при помощи предыдущих методов GPGPU являетсято, что эти методы не используют блоки исполнения вершинных шейдеров в предыдущихнеунифицированных архитектурах, данные хранятся в текстурах, а выводятся вовнеэкранный буфер, а многопроходные алгоритмы используют пиксельные шейдерныеблоки. В ограничения GPGPU можно включить: недостаточно эффективноеиспользование аппаратных возможностей, ограничения полосой пропускания памяти,отсутствие операции scatter (только gather), обязательное использование графическогоAPI.Основные преимущества <strong>CUDA</strong> по сравнению с предыдущими методами GPGPUвытекают из того, что эта архитектура спроектирова<strong>на</strong> для эффективного использованияне<strong>графических</strong> вычислений <strong>на</strong> GPU и использует язык программирования C, не требуяпереноса алгоритмов в удобный для концепции графического конвейера вид. <strong>CUDA</strong>предлагает новый путь вычислений <strong>на</strong> GPU, не использующий графические API,предлагающий произвольный доступ к памяти (scatter или gather). Такая архитектуралише<strong>на</strong> недостатков GPGPU и использует все исполнительные блоки, а также расширяетвозможности за счёт целочисленной математики и операций битового сдвига.Кроме того, <strong>CUDA</strong> открывает некоторые аппаратные возможности, недоступные из<strong>графических</strong> API, такие как разделяемая память. Это память небольшого объёма (16


килобайт <strong>на</strong> мультипроцессор), к которой имеют доступ блоки потоков. О<strong>на</strong> позволяеткэшировать <strong>на</strong>иболее часто используемые данные и может обеспечить более высокуюскорость, по сравнению с использованием текстурных выборок для этой задачи. Что, всвою очередь, снижает чувствительность к пропускной способности параллельныхалгоритмов во многих приложениях. Например, это полезно для линейной алгебры,быстрого преобразования Фурье и фильтров обработки изображений.Удобнее в <strong>CUDA</strong> и доступ к памяти. Программный код в <strong>графических</strong> API выводитданные в виде 32-х з<strong>на</strong>чений с плавающей точкой оди<strong>на</strong>рной точности (RGBA з<strong>на</strong>ченияодновременно в восемь render target) в заранее предопределённые области, а <strong>CUDA</strong>поддерживает scatter запись <strong>—</strong> неограниченное число записей по любому адресу. Такиепреимущества делают возможным выполнение <strong>на</strong> GPU некоторых алгоритмов, которыеневозможно эффективно реализовать при помощи методов GPGPU, основанных <strong>на</strong><strong>графических</strong> API.Также, графические API в обязательном порядке хранят данные в текстурах, что требуетпредварительной упаковки больших массивов в текстуры, что усложняет алгоритм изаставляет использовать специальную адресацию. А <strong>CUDA</strong> позволяет читать данные полюбому адресу. Ещё одним преимуществом <strong>CUDA</strong> является оптимизированный обменданными между CPU и GPU. А для разработчиков, желающих получить доступ к низкомууровню (<strong>на</strong>пример, при <strong>на</strong>писании другого языка программирования), <strong>CUDA</strong> предлагаетвозможность низкоуровневого программирования <strong>на</strong> ассемблере.История развития <strong>CUDA</strong>Разработка <strong>CUDA</strong> была анонсирова<strong>на</strong> вместе с чипом G80 в ноябре 2006, а релизпубличной бета-версии <strong>CUDA</strong> SDK состоялся в феврале 2007 года. Версия 1.0 вышла виюне 2007 года под запуск в продажу решений Tesla, основанных <strong>на</strong> чипе G80, ипред<strong>на</strong>з<strong>на</strong>ченных для рынка высокопроизводительных вычислений. Затем, в конце годавышла бета-версия <strong>CUDA</strong> 1.1, которая, несмотря <strong>на</strong> малоз<strong>на</strong>чительное увеличение номераверсии, ввела довольно много нового.Из появившегося в <strong>CUDA</strong> 1.1 можно отметить включение <strong>CUDA</strong>-функцио<strong>на</strong>льности вобычные видеодрайверы <strong>NVIDIA</strong>. Это оз<strong>на</strong>чало, что в требованиях к любой <strong>CUDA</strong>программе достаточно было указать видеокарту серии GeForce 8 и выше, а такжеминимальную версию драйверов 169.xx. Это очень важно для разработчиков, присоблюдении этих условий <strong>CUDA</strong> программы будут работать у любого пользователя.Также было добавлено асинхронное выполнение вместе с копированием данных (толькодля чипов G84, G86, G92 и выше), асинхрон<strong>на</strong>я пересылка данных в видеопамять,атомарные операции доступа к памяти, поддержка 64-битных версий Windows ивозможность мультичиповой работы <strong>CUDA</strong> в режиме SLI.На данный момент актуальной является версия для решений <strong>на</strong> основе GT200 <strong>—</strong> <strong>CUDA</strong>2.0, вышедшая вместе с линейкой GeForce GTX 200. Бета-версия была выпуще<strong>на</strong> ещёвесной 2008 года. Во второй версии появились: поддержка вычислений двойной точности(аппарат<strong>на</strong>я поддержка только у GT200), <strong>на</strong>конец-то поддерживается Windows Vista (32 и64-битные версии) и Mac OS X, добавлены средства отладки и профилирования,поддерживаются 3D текстуры, оптимизирован<strong>на</strong>я пересылка данных.Что касается вычислений с двойной точностью, то их скорость <strong>на</strong> текущем аппаратномпоколении ниже оди<strong>на</strong>рной точности в несколько раз. Причины рассмотрены в <strong>на</strong>шейбазовой статье по GeForce GTX 280. Реализация в GT200 этой поддержки заключается в


том, блоки FP32 не используются для получения результата в четыре раза меньшем темпе,для поддержки FP64 вычислений в <strong>NVIDIA</strong> решили сделать выделенные вычислительныеблоки. И в GT200 их в десять раз меньше, чем блоков FP32 (по одному блоку двойнойточности <strong>на</strong> каждый мультипроцессор).Реально производительность может быть даже ещё меньше, так как архитектураоптимизирова<strong>на</strong> для 32-битного чтения из памяти и регистров, кроме того, двой<strong>на</strong>яточность не нуж<strong>на</strong> в <strong>графических</strong> приложениях, и в GT200 о<strong>на</strong> сдела<strong>на</strong> скорее,чтобы просто была. Да и современные четырехъядерные процессоры показывают не<strong>на</strong>много меньшую реальную производительность. Но будучи даже в 10 раз медленнее, чемоди<strong>на</strong>р<strong>на</strong>я точность, такая поддержка полез<strong>на</strong> для схем со смешанной точностью. Од<strong>на</strong> израспространенных техник <strong>—</strong> получить из<strong>на</strong>чально приближенные результаты води<strong>на</strong>рной точности, и затем их уточнить в двойной. Теперь это можно сделать прямо <strong>на</strong>видеокарте, без пересылки промежуточных данных к CPU.Ещё од<strong>на</strong> полез<strong>на</strong>я особенность <strong>CUDA</strong> 2.0 не имеет отношения к GPU, как ни странно.Просто теперь можно компилировать код <strong>CUDA</strong> в высокоэффективный многопоточныйSSE код для быстрого исполнения <strong>на</strong> центральном процессоре. То есть, теперь этавозможность годится не только для отладки, но и реального использования <strong>на</strong> системахбез видеокарты <strong>NVIDIA</strong>. Ведь использование <strong>CUDA</strong> в обычном коде сдерживается тем,что видеокарты <strong>NVIDIA</strong> хоть и самые популярные среди выделенных видеорешений, ноимеются не во всех системах. И до версии 2.0 в таких случаях пришлось бы делать дваразных кода: для <strong>CUDA</strong> и отдельно для CPU. А теперь можно выполнять любую <strong>CUDA</strong>программу <strong>на</strong> CPU с высокой эффективностью, пусть и с меньшей скоростью, чем <strong>на</strong>видеочипах.Решения с поддержкой <strong>NVIDIA</strong> <strong>CUDA</strong>Все видеокарты, обладающие поддержкой <strong>CUDA</strong>, могут помочь в ускорении большинстватребовательных задач, <strong>на</strong>чи<strong>на</strong>я от аудио- и видеообработки, и заканчивая медициной и<strong>на</strong>учными исследованиями. Единственное реальное ограничение состоит в том, чтомногие <strong>CUDA</strong> программы требуют минимум 256 мегабайт видеопамяти, и это <strong>—</strong> од<strong>на</strong> изважнейших технических характеристик для <strong>CUDA</strong>-приложений.Актуальный список поддерживающих <strong>CUDA</strong> продуктов можно получить <strong>на</strong> вебсайте<strong>NVIDIA</strong>. На момент <strong>на</strong>писания статьи расчёты <strong>CUDA</strong> поддерживали все продукты серийGeForce 200, GeForce 9 и GeForce 8, в том числе и мобильные продукты, <strong>на</strong>чи<strong>на</strong>я сGeForce 8400M, а также и чипсеты GeForce 8100, 8200 и 8300. Также поддержкой <strong>CUDA</strong>обладают современные продукты Quadro и все Tesla: S1070, C1060, C870, D870 и S870.


Особо отметим, что вместе с новыми видеокартами GeForce GTX 260 и 280, былианонсированы и соответствующие решения для высокопроизводительных вычислений:Tesla C1060 и S1070 (представленные <strong>на</strong> фото выше), которые будут доступны дляприобретения осенью этого года. GPU в них применён тот же <strong>—</strong> GT200, в C1060 он один,в S1070 <strong>—</strong> четыре. Зато, в отличие от игровых решений, в них используется по четырегигабайта памяти <strong>на</strong> каждый чип. Из минусов разве что меньшая частота памяти и ПСП,чем у игровых карт, обеспечивающая по 102 гигабайт/с <strong>на</strong> чип.Состав <strong>NVIDIA</strong> <strong>CUDA</strong><strong>CUDA</strong> включает два API: высокого уровня (<strong>CUDA</strong> Runtime API) и низкого (<strong>CUDA</strong> DriverAPI), хотя в одной программе одновременное использование обоих невозможно, нужноиспользовать или один или другой. Высокоуровневый работает «сверху»низкоуровневого, все вызовы runtime транслируются в простые инструкции,обрабатываемые низкоуровневым Driver API. Но даже «высокоуровневый» APIпредполагает з<strong>на</strong>ния об устройстве и работе видеочипов <strong>NVIDIA</strong>, слишком высокогоуровня абстракции там нет.


Есть и ещё один уровень, даже более высокий <strong>—</strong> две библиотеки:CUBLAS <strong>—</strong> <strong>CUDA</strong> вариант BLAS (Basic Linear Algebra Subprograms), пред<strong>на</strong>з<strong>на</strong>ченныйдля вычислений задач линейной алгебры и использующий прямой доступ к ресурсамGPU;CUFFT <strong>—</strong> <strong>CUDA</strong> вариант библиотеки Fast Fourier Transform для расчёта быстрогопреобразования Фурье, широко используемого при обработке сиг<strong>на</strong>лов. Поддерживаютсяследующие типы преобразований: complex-complex (C2C), real-complex (R2C) и complexreal(C2R).Рассмотрим эти библиотеки подробнее. CUBLAS <strong>—</strong> это переведённые <strong>на</strong> язык <strong>CUDA</strong>стандартные алгоритмы линейной алгебры, <strong>на</strong> данный момент поддерживается толькоопределённый <strong>на</strong>бор основных функций CUBLAS. Библиотеку очень легко использовать:нужно создать матрицу и векторные объекты в памяти видеокарты, заполнить ихданными, вызвать требуемые функции CUBLAS, и загрузить результаты из видеопамятиобратно в системную. CUBLAS содержит специальные функции для создания иуничтожения объектов в памяти GPU, а также для чтения и записи данных в эту память.Поддерживаемые функции BLAS: уровни 1, 2 и 3 для действительных чисел, уровень 1CGEMM для комплексных. Уровень 1 <strong>—</strong> это векторно-векторные операции, уровень 2 <strong>—</strong>векторно-матричные операции, уровень 3 <strong>—</strong> матрично-матричные операции.CUFFT <strong>—</strong> <strong>CUDA</strong> вариант функции быстрого преобразования Фурье <strong>—</strong> широкоиспользуемой и очень важной при а<strong>на</strong>лизе сиг<strong>на</strong>лов, фильтрации и т.п. CUFFTпредоставляет простой интерфейс для эффективного <strong>вычисления</strong> FFT <strong>на</strong> видеочипахпроизводства <strong>NVIDIA</strong> без необходимости в разработке собственного варианта FFT дляGPU. <strong>CUDA</strong> вариант FFT поддерживает 1D, 2D, и 3D преобразования комплексных идействительных данных, пакетное исполнение для нескольких 1D трансформаций в


параллели, размеры 2D и 3D трансформаций могут быть в пределах [2, 16384], для 1Dподдерживается размер до 8 миллионов элементов.Основы создания программ <strong>на</strong> <strong>CUDA</strong>Для понимания дальнейшего текста следует разбираться в базовых архитектурныхособенностях видеочипов <strong>NVIDIA</strong>. GPU состоит из нескольких кластеров текстурныхблоков (Texture Processing Cluster). Каждый кластер состоит из укрупнённого блокатекстурных выборок и двух-трех потоковых мультипроцессоров, каждый из которыхсостоит из восьми вычислительных устройств и двух суперфункцио<strong>на</strong>льных блоков. Всеинструкции выполняются по принципу SIMD, когда од<strong>на</strong> инструкция применяется ковсем потокам в warp (термин из текстильной промышленности, в <strong>CUDA</strong> это группа из 32потоков <strong>—</strong> минимальный объём данных, обрабатываемых мультипроцессорами). Этотспособ выполнения <strong>на</strong>звали SIMT (single instruction multiple threads <strong>—</strong> од<strong>на</strong> инструкция имного потоков).Каждый из мультипроцессоров имеет определённые ресурсы. Так, есть специаль<strong>на</strong>яразделяемая память объемом 16 килобайт <strong>на</strong> мультипроцессор. Но это не кэш, так какпрограммист может использовать её для любых нужд, подобно Local Store в SPUпроцессоров Cell. Эта разделяемая память позволяет обмениваться информацией междупотоками одного блока. Важно, что все потоки одного блока всегда выполняются одним итем же мультипроцессором. А потоки из разных блоков обмениваться данными не могут,и нужно помнить это ограничение. Разделяемая память часто бывает полезной, кроме техслучаев, когда несколько потоков обращаются к одному банку памяти.Мультипроцессоры могут обращаться и к видеопамяти, но с большими задержками ихудшей пропускной способностью. Для ускорения доступа и снижения частотыобращения к видеопамяти, у мультипроцессоров есть по 8 килобайт кэша <strong>на</strong> константы итекстурные данные.


Мультипроцессор использует 8192-16384 (для G8x/G9x и GT2xx, соответственно)регистра, общие для всех потоков всех блоков, выполняемых <strong>на</strong> нём. Максимальное числоблоков <strong>на</strong> один мультипроцессор для G8x/G9x равно восьми, а число warp <strong>—</strong> 24 (768потоков <strong>на</strong> один мультипроцессор). Всего топовые видеокарты серий GeForce 8 и 9 могутобрабатывать до 12288 потоков единовременно. GeForce GTX 280 <strong>на</strong> основе GT200предлагает до 1024 потоков <strong>на</strong> мультипроцессор, в нём есть 10 кластеров по тримультипроцессора, обрабатывающих до 30720 потоков. З<strong>на</strong>ние этих ограниченийпозволяет оптимизировать алгоритмы под доступные ресурсы.Первым шагом при переносе существующего приложения <strong>на</strong> <strong>CUDA</strong> является егопрофилирование и определение участков кода, являющихся «бутылочным горлышком»,тормозящим работу. Если среди таких участков есть подходящие для быстрогопараллельного исполнения, эти функции переносятся <strong>на</strong> Cи расширения <strong>CUDA</strong> длявыполнения <strong>на</strong> GPU. Программа компилируется при помощи поставляемого <strong>NVIDIA</strong>компилятора, который генерирует код и для CPU, и для GPU. При исполнениипрограммы, центральный процессор выполняет свои порции кода, а GPU выполняет<strong>CUDA</strong> код с <strong>на</strong>иболее тяжелыми параллельными <strong>вычисления</strong>ми. Эта часть,пред<strong>на</strong>з<strong>на</strong>чен<strong>на</strong>я для GPU, <strong>на</strong>зывается ядром (kernel). В ядре определяются операции,которые будут исполнены <strong>на</strong>д данными.Видеочип получает ядро и создает копии для каждого элемента данных. Эти копии<strong>на</strong>зываются потоками (thread). Поток содержит счётчик, регистры и состояние. Длябольших объёмов данных, таких как обработка изображений, запускаются миллионыпотоков. Потоки выполняются группами по 32 штуки, <strong>на</strong>зываемыми warp'ы. Warp'ам<strong>на</strong>з<strong>на</strong>чается исполнение <strong>на</strong> определенных потоковых мультипроцессорах. Каждыймультипроцессор состоит из восьми ядер <strong>—</strong> потоковых процессоров, которые выполняютодну инструкцию MAD за один такт. Для исполнения одного 32-поточного warp'атребуется четыре такта работы мультипроцессора (речь о частоте shader domain, котораярав<strong>на</strong> 1.5 ГГц и выше).Мультипроцессор не является традиционным многоядерным процессором, он отличноприспособлен для многопоточности, поддерживая до 32 warp'ов единовременно. Каждыйтакт аппаратное обеспечение выбирает, какой из warp'ов исполнять, и переключается отодного к другому без потерь в тактах. Если проводить а<strong>на</strong>логию с центральнымпроцессором, это похоже <strong>на</strong> одновременное исполнение 32 программ и переключениемежду ними каждый такт без потерь <strong>на</strong> переключение контекста. Реально ядра CPUподдерживают единовременное выполнение одной программы и переключаются <strong>на</strong>другие с задержкой в сотни тактов.Модель программирования <strong>CUDA</strong>Повторимся, что <strong>CUDA</strong> использует параллельную модель вычислений, когда каждый изSIMD процессоров выполняет ту же инструкцию <strong>на</strong>д разными элементами данныхпараллельно. GPU является вычислительным устройством, сопроцессором (device) дляцентрального процессора (host), обладающим собственной памятью и обрабатывающимпараллельно большое количество потоков. Ядром (kernel) <strong>на</strong>зывается функция для GPU,исполняемая потоками (а<strong>на</strong>логия из 3D графики <strong>—</strong> шейдер).Мы говорили выше, что видеочип отличается от CPU тем, что может обрабатыватьодновременно десятки тысяч потоков, что обычно для графики, которая хорошораспараллеливается. Каждый поток скалярен, не требует упаковки данных в 4-компонентные векторы, что удобнее для большинства задач. Количество логических


потоков и блоков потоков превосходит количество физических исполнительныхустройств, что даёт хорошую масштабируемость для всего модельного ряда решенийкомпании.Модель программирования в <strong>CUDA</strong> предполагает группирование потоков. Потокиобъединяются в блоки потоков (thread block) <strong>—</strong> одномерные или двумерные сеткипотоков, взаимодействующих между собой при помощи разделяемой памяти и точексинхронизации. Программа (ядро, kernel) исполняется <strong>на</strong>д сеткой (grid) блоков потоков(thread blocks), см. рисунок ниже. Одновременно исполняется од<strong>на</strong> сетка. Каждый блокможет быть одно-, двух- или трехмерным по форме, и может состоять из 512 потоков <strong>на</strong>текущем аппаратном обеспечении.Блоки потоков выполняются в виде небольших групп, <strong>на</strong>зываемых варп (warp), размеркоторых <strong>—</strong> 32 потока. Это минимальный объём данных, которые могут обрабатываться вмультипроцессорах. И так как это не всегда удобно, <strong>CUDA</strong> позволяет работать и сблоками, содержащими от 64 до 512 потоков.Группировка блоков в сетки позволяет уйти от ограничений и применить ядро к большемучислу потоков за один вызов. Это помогает и при масштабировании. Если у GPUнедостаточно ресурсов, он будет выполнять блоки последовательно. В обратном случае,блоки могут выполняться параллельно, что важно для оптимального распределенияработы <strong>на</strong> видеочипах разного уровня, <strong>на</strong>чи<strong>на</strong>я от мобильных и интегрированных.Модель памяти <strong>CUDA</strong>Модель памяти в <strong>CUDA</strong> отличается возможностью побайтной адресации, поддержкой какgather, так и scatter. Доступно довольно большое количество регистров <strong>на</strong> каждыйпотоковый процессор, до 1024 штук. Доступ к ним очень быстрый, хранить в них можно32-битные целые или числа с плавающей точкой.


Каждый поток имеет доступ к следующим типам памяти:Глобаль<strong>на</strong>я память <strong>—</strong> самый большой объём памяти, доступный для всехмультипроцессоров <strong>на</strong> видеочипе, размер составляет от 256 мегабайт до 1.5 гигабайт <strong>на</strong>текущих решениях (и до 4 Гбайт <strong>на</strong> Tesla). Обладает высокой пропускной способностью,более 100 гигабайт/с для топовых решений <strong>NVIDIA</strong>, но очень большими задержками внесколько сот тактов. Не кэшируется, поддерживает обобщённые инструкции load и store,и обычные указатели <strong>на</strong> память.Локаль<strong>на</strong>я память <strong>—</strong> это небольшой объём памяти, к которому имеет доступ толькоодин потоковый процессор. О<strong>на</strong> относительно медлен<strong>на</strong>я <strong>—</strong> такая же, как и глобаль<strong>на</strong>я.Разделяемая память <strong>—</strong> это 16-килобайтный (в видеочипах нынешней архитектуры) блокпамяти с общим доступом для всех потоковых процессоров в мультипроцессоре. Этапамять весьма быстрая, такая же, как регистры. О<strong>на</strong> обеспечивает взаимодействиепотоков, управляется разработчиком <strong>на</strong>прямую и имеет низкие задержки. Преимуществаразделяемой памяти: использование в виде управляемого программистом кэша первогоуровня, снижение задержек при доступе исполнительных блоков (ALU) к данным,сокращение количества обращений к глобальной памяти.Память констант <strong>—</strong> область памяти объемом 64 килобайта (то же <strong>—</strong> для нынешнихGPU), доступ<strong>на</strong>я только для чтения всеми мультипроцессорами. О<strong>на</strong> кэшируется по 8килобайт <strong>на</strong> каждый мультипроцессор. Довольно медлен<strong>на</strong>я <strong>—</strong> задержка в несколько соттактов при отсутствии нужных данных в кэше.Текстур<strong>на</strong>я память <strong>—</strong> блок памяти, доступный для чтения всеми мультипроцессорами.Выборка данных осуществляется при помощи текстурных блоков видеочипа, поэтомупредоставляются возможности линейной интерполяции данных без дополнительныхзатрат. Кэшируется по 8 килобайт <strong>на</strong> каждый мультипроцессор. Медлен<strong>на</strong>я, какглобаль<strong>на</strong>я <strong>—</strong> сотни тактов задержки при отсутствии данных в кэше.


Естественно, что глобаль<strong>на</strong>я, локаль<strong>на</strong>я, текстур<strong>на</strong>я и память констант <strong>—</strong> это физическиод<strong>на</strong> и та же память, извест<strong>на</strong>я как локаль<strong>на</strong>я видеопамять видеокарты. Их отличия вразличных алгоритмах кэширования и моделях доступа. Центральный процессор можетобновлять и запрашивать только внешнюю память: глобальную, константную итекстурную.Из <strong>на</strong>писанного выше понятно, что <strong>CUDA</strong> предполагает специальный подход кразработке, не совсем такой, как принят в программах для CPU. Нужно помнить о разныхтипах памяти, о том, что локаль<strong>на</strong>я и глобаль<strong>на</strong>я память не кэшируется и задержки придоступе к ней гораздо выше, чем у регистровой памяти, так как о<strong>на</strong> физически <strong>на</strong>ходитсяв отдельных микросхемах.Типичный, но не обязательный шаблон решения задач:задача разбивается <strong>на</strong> подзадачи;входные данные делятся <strong>на</strong> блоки, которые вмещаются в разделяемую память;каждый блок обрабатывается блоком потоков;подблок подгружается в разделяемую память из глобальной;<strong>на</strong>д данными в разделяемой памяти проводятся соответствующие <strong>вычисления</strong>;результаты копируются из разделяемой памяти обратно в глобальную.Среда программированияВ состав <strong>CUDA</strong> входят runtime библиотеки:общая часть, предоставляющая встроенные векторные типы и подмножествавызовов RTL, поддерживаемые <strong>на</strong> CPU и GPU;CPU-компонента, для управления одним или несколькими GPU;GPU-компонента, предоставляющая специфические функции для GPU.Основной процесс приложения <strong>CUDA</strong> работает <strong>на</strong> универсальном процессоре (host), онзапускает несколько копий процессов kernel <strong>на</strong> видеокарте. Код для CPU делаетследующее: инициализирует GPU, распределяет память <strong>на</strong> видеокарте и системе,


копирует константы в память видеокарты, запускает несколько копий процессов kernel <strong>на</strong>видеокарте, копирует полученный результат из видеопамяти, освобождает память изавершает работу.В качестве примера для понимания приведем CPU код для сложения векторов,представленный в <strong>CUDA</strong>:Функции, исполняемые видеочипом, имеют следующие ограничения: отсутствуетрекурсия, нет статических переменных внутри функций и переменного числа аргументов.Поддерживается два вида управления памятью: линей<strong>на</strong>я память с доступом по 32-битным указателям, и <strong>CUDA</strong>-массивы с доступом только через функции текстурнойвыборки.Программы <strong>на</strong> <strong>CUDA</strong> могут взаимодействовать с графическими API: для рендерингаданных, сгенерированных в программе, для считывания результатов рендеринга и ихобработки средствами <strong>CUDA</strong> (<strong>на</strong>пример, при реализации фильтров постобработки). Дляэтого ресурсы <strong>графических</strong> API могут быть отображены (с получением адреса ресурса) впространство глобальной памяти <strong>CUDA</strong>. Поддерживаются следующие типы ресурсов<strong>графических</strong> API: Buffer Objects (PBO / VBO) в OpenGL, вершинные буферы и текстуры(2D, 3D и кубические карты) Direct3D9.Стадии компиляции <strong>CUDA</strong>-приложения:


Файлы исходного кода <strong>на</strong> <strong>CUDA</strong> C компилируются при помощи программы NVCC,которая является оболочкой <strong>на</strong>д другими инструментами, и вызывает их: cudacc, g++, cl идр. NVCC генерирует: код для центрального процессора, который компилируется вместе состальными частями приложения, <strong>на</strong>писанными <strong>на</strong> чистом Си, и объектный код PTX длявидеочипа. Исполнимые файлы с кодом <strong>на</strong> <strong>CUDA</strong> в обязательном порядке требуют<strong>на</strong>личия библиотек <strong>CUDA</strong> runtime library (cudart) и <strong>CUDA</strong> core library (cuda).Оптимизация программ <strong>на</strong> <strong>CUDA</strong>Естественно, в рамках обзорной статьи невозможно рассмотреть серьёзные вопросыоптимизации в <strong>CUDA</strong> программировании. Поэтому просто вкратце расскажем о базовыхвещах. Для эффективного использования возможностей <strong>CUDA</strong> нужно забыть прообычные методы <strong>на</strong>писания программ для CPU, и использовать те алгоритмы, которыехорошо распараллеливаются <strong>на</strong> тысячи потоков. Также важно <strong>на</strong>йти оптимальное местодля хранения данных (регистры, разделяемая память и т.п.), минимизировать передачуданных между CPU и GPU, использовать буферизацию.В общих чертах, при оптимизации программы <strong>CUDA</strong> нужно постараться добитьсяоптимального баланса между размером и количеством блоков. Большее количествопотоков в блоке снизит влияние задержек памяти, но снизит и доступное число регистров.Кроме того, блок из 512 потоков неэффективен, сама <strong>NVIDIA</strong> рекомендует использоватьблоки по 128 или 256 потоков, как компромиссное з<strong>на</strong>чение для достижения оптимальныхзадержек и количества регистров.Среди основных моментов оптимизации программ <strong>CUDA</strong>: как можно более активноеиспользование разделяемой памяти, так как о<strong>на</strong> з<strong>на</strong>чительно быстрее глобальнойвидеопамяти видеокарты; операции чтения и записи из глобальной памяти должны бытьобъединены (coalesced) по возможности. Для этого нужно использовать специальныетипы данных для чтения и записи сразу по 32/64/128 бита данных одной операцией. Еслиоперации чтения трудно объединить, можно попробовать использовать текстурныевыборки.Выводы


Представлен<strong>на</strong>я компанией <strong>NVIDIA</strong> программно-аппарат<strong>на</strong>я архитектура для расчётов <strong>на</strong>видеочипах <strong>CUDA</strong> хорошо подходит для решения широкого круга задач с высокимпараллелизмом. <strong>CUDA</strong> работает <strong>на</strong> большом количестве видеочипов <strong>NVIDIA</strong>, и улучшаетмодель программирования GPU, з<strong>на</strong>чительно упрощая её и добавляя большое количествовозможностей, таких как разделяемая память, возможность синхронизации потоков,<strong>вычисления</strong> с двойной точностью и целочисленные операции.<strong>CUDA</strong> <strong>—</strong> это доступ<strong>на</strong>я каждому разработчику ПО технология, её может использоватьлюбой программист, з<strong>на</strong>ющий язык Си. Придётся только привыкнуть к иной парадигмепрограммирования, присущей параллельным <strong>вычисления</strong>м. Но если алгоритм в принципехорошо распараллеливается, то изучение и затраты времени <strong>на</strong> программирование <strong>на</strong><strong>CUDA</strong> вернутся в многократном размере.Вполне вероятно, что в силу широкого распространения видеокарт в мире, развитиепараллельных вычислений <strong>на</strong> GPU сильно повлияет <strong>на</strong> индустриювысокопроизводительных вычислений. Эти возможности уже вызвали большой интерес в<strong>на</strong>учных кругах, да и не только в них. Ведь потенциальные возможности ускоренияхорошо поддающихся распараллеливанию алгоритмов (<strong>на</strong> доступном аппаратномобеспечении, что не менее важно) сразу в десятки раз бывают не так часто.Универсальные процессоры развиваются довольно медленно, у них нет таких скачковпроизводительности. По сути, пусть это и звучит слишком громко, все нуждающиеся вбыстрых вычислителях теперь могут получить недорогой персо<strong>на</strong>льный суперкомпьютер<strong>на</strong> своём столе, иногда даже не вкладывая дополнительных средств, так как видеокарты<strong>NVIDIA</strong> широко распространены. Не говоря уже об увеличении эффективности втерми<strong>на</strong>х GFLOPS/$ и GFLOPS/Вт, которые так нравятся производителям GPU.Будущее множества вычислений явно за параллельными алгоритмами, почти все новыерешения и инициативы <strong>на</strong>правлены в эту сторону. Пока что, впрочем, развитие новыхпарадигм <strong>на</strong>ходится <strong>на</strong> <strong>на</strong>чальном этапе, приходится вручную создавать потоки ипланировать доступ к памяти, что усложняет задачи по сравнению с привычнымпрограммированием. Но технология <strong>CUDA</strong> сделала шаг в правильном <strong>на</strong>правлении и вней явно проглядывается успешное решение, особенно если <strong>NVIDIA</strong> удастся убедить какможно разработчиков в его пользе и перспективах.Но, конечно, GPU не заменят CPU. В их нынешнем виде они и не пред<strong>на</strong>з<strong>на</strong>чены дляэтого. Сейчас что видеочипы движутся постепенно в сторону CPU, становясь всё болееуниверсальными (расчёты с плавающей точкой оди<strong>на</strong>рной и двойной точности,целочисленные <strong>вычисления</strong>), так и CPU становятся всё более «параллельными»,обзаводясь большим количеством ядер, технологиями многопоточности, не говоря пропоявление блоков SIMD и проектов гетерогенных процессоров. Скорее всего, GPU и CPUв будущем просто сольются. Известно, что многие компании, в том числе Intel и AMDработают <strong>на</strong>д подобными проектами. И неважно, будут ли GPU поглощены CPU, или<strong>на</strong>оборот.В статье мы в основном говорили о преимуществах <strong>CUDA</strong>. Но есть и ложечка дёгтя. Одиниз немногочисленных недостатков <strong>CUDA</strong> <strong>—</strong> слабая переносимость. Эта архитектураработает только <strong>на</strong> видеочипах этой компании, да ещё и не <strong>на</strong> всех, а <strong>на</strong>чи<strong>на</strong>я с серииGeForce 8 и 9 и соответствующих Quadro и Tesla. Да, таких решений в мире очень много,<strong>NVIDIA</strong> приводит цифру в 90 миллионов <strong>CUDA</strong>-совместимых видеочипов. Это простоотлично, но ведь конкуренты предлагают свои решения, отличные от <strong>CUDA</strong>. Так, у AMDесть Stream Computing, у Intel в будущем будет Ct.


Которая из технологий победит, станет распространённой и проживёт дольше остальных<strong>—</strong> покажет только время. Но у <strong>CUDA</strong> есть неплохие шансы, так как по сравнению сStream Computing, <strong>на</strong>пример, о<strong>на</strong> представляет более развитую и удобную дляиспользования среду программирования <strong>на</strong> обычном языке Си. Возможно, в определениипоможет третья сторо<strong>на</strong>, выпустив некое общее решение. К примеру, в следующемобновлении DirectX под версией 11, компанией Microsoft обещаны вычислительныешейдеры, которые и могут стать неким усреднённым решением, устраивающим всех, илипочти всех.Судя по предварительным данным, этот новый тип шейдеров заимствует многое измодели <strong>CUDA</strong>. И программируя в этой среде уже сейчас, можно получить преимуществасразу и необходимые <strong>на</strong>выки для будущего. С точки зрения высокопроизводительныхвычислений, у DirectX также есть явный недостаток в виде плохой переносимости, так какэтот API ограничен платформой Windows. Впрочем, разрабатывается и ещё один стандарт<strong>—</strong> открытая мультиплатформен<strong>на</strong>я инициатива OpenCL, которая поддерживаетсябольшинством компаний, среди которых <strong>NVIDIA</strong>, AMD, Intel, IBM и многие другие.Не забывайте, что в следующей статье по <strong>CUDA</strong> вас ждёт исследование конкретныхпрактических применений <strong>на</strong>учных и других не<strong>графических</strong> вычислений, выполненныхразработчиками из разных уголков <strong>на</strong>шей планеты при помощи <strong>NVIDIA</strong> <strong>CUDA</strong>.Алексей Берилло (sbe@ixbt.com)Обсудить в конференции (комментариев: 287)Опубликовано <strong>—</strong> 23 сентября 2008 г.Другие обсуждения в конференции:o [22:48] Выбор видеокарты для готовой конфигурации ПК (часть 3) (2101сообщений)o [22:44] AMD(ATI) vs <strong>NVIDIA</strong> (часть 18) (1275 сообщений)o [22:25] AMD Radeon HD 7750/7770 (Cape Verde) (198 сообщений)o [22:25] Имеет ли смысл ждать чего-то интересного под AGP? / Выбор картып… (1593 сообщений)o [21:06] Выбор видеокарты до $100 (часть 2) (453 сообщений)Технология <strong>NVIDIA</strong> <strong>CUDA</strong> - это фундаментально новая архитектура вычислений <strong>на</strong>GPU, пред<strong>на</strong>з<strong>на</strong>чен<strong>на</strong>я для решения комплекса вычислительных задач потребителей,бизнеса и технической индустрии. Технология <strong>CUDA</strong> (compute unified device architecture -<strong>вычисления</strong> <strong>на</strong> унифицированной аппаратной архитектуре) предоставляет приложениям,активно работающим с данными, доступ к потрясающим процессинговым мощностям<strong>графических</strong> процессоров <strong>NVIDIA</strong> через революционную вычислительную архитектуру,связанную с новыми возможностями. Придавая з<strong>на</strong>чение большей производительности иупрощению разработки программного обеспечения через стандартный язык C, технология<strong>CUDA</strong> даёт возможность разработчикам создавать решения для интенсивной работы сданными в кратчайшие сроки.


Что это за технология "<strong>CUDA</strong>"?Вычисления <strong>на</strong> GPU с технологией <strong>CUDA</strong> - это инновационное сочетаниевычислительных способностей следующего поколения <strong>графических</strong> процессоров <strong>NVIDIA</strong>,доступныз через стандартный язык 'C'. Тогда как предыдущее поколение <strong>графических</strong>процессоров было основано <strong>на</strong> "потоковых шейдерных программах", программисты<strong>CUDA</strong> могут испльзовать 'C' для создания программ, вызывающих потоки также, как и <strong>на</strong>традиционных многопоточных CPU (Блин, традиционных. _Ни у кого_ из моих з<strong>на</strong>комыхнет двуядерника. Да даже Пня4 с гипер-трейдингом.). Но многоядерные процессорымогут исполнять лишь несколько потоков одновременно, а графические процессоры<strong>NVIDIA</strong> с технологией <strong>CUDA</strong> обработают сразу тысячи потоков с высоким уровнеминформационной <strong>на</strong>грузки. (Блин. Вот у "них" есть thread и flow. А как я должен <strong>на</strong>звать"поток", чтобы не повториться?)Од<strong>на</strong> из <strong>на</strong>иболее важных инноваций в технологии <strong>CUDA</strong> - возможность объединенияпотоков <strong>графических</strong> процессоров <strong>NVIDIA</strong> для решения одной задачи, что позволяетприложениям работать с большей эффективностью. Графические процессоры <strong>NVIDIA</strong> стехнологией <strong>CUDA</strong> имеют параллельные кэши данных, которых сохраняют частоиспользуемую информацию прямо в GPU. Хранение информации в GPU позволяетисполнять потоки, использующие общую информацию, во много раз быстрее, чем если быо<strong>на</strong> запрашивалась из системной памяти. Эта прогрессив<strong>на</strong>я технология даёт возможностьпользователям решать вычислительные задачи в режиме реального времени.Какие преимущества получают приложения от <strong>CUDA</strong>?Вычисления <strong>на</strong> GPU подходят для решения широкого спектра задач, связанных собработкой больших объёмов информации. Например игровые приложения могутиспользовать графический процессор <strong>NVIDIA</strong> для физических расчётов, поднимающихпроизводительность и эффектность <strong>на</strong> новый уровень. Также, коммерческие приложения,используемые для разработки программ или а<strong>на</strong>лиза больших массивов данных, ранеетребовавших высокой производительности системы, получат преимущество отиспользования <strong>на</strong> рабочей станции или сервере с технологией <strong>CUDA</strong>. Это перелом втехнологиях, позволяющий выполнять а<strong>на</strong>лиз и решение задач любого рода в режимереального времени. Кроме того, <strong>на</strong>учные приложения, которые требуют высокойинтенсивности вычислений больше не будут занимать всё процессорное время.Вычисления с <strong>CUDA</strong> предоставляет платформу с высоким уровнем производительностивне зависимости от предполагаемого использования.Почему используется технология <strong>CUDA</strong>?Производительность. Графические процессоры <strong>NVIDIA</strong> предоставляют немыслимыйуровень производительности для приложений, интенсивно работающих с данными.Технология <strong>CUDA</strong> предоставляет стандартное, широко доступное решение для поставкиновых приложений с беспрецендентными возможностями.Совместимость. Приложения, разработанные с использованием <strong>CUDA</strong> C-компилятасовместимы с будующим поколением <strong>графических</strong> процессоров <strong>NVIDIA</strong> (лучше бы онипредыдущее добавили). Разработчики, вкладывающие силы в разработку приложений дляGPU, сразу получат преимущество от использования производительных <strong>графических</strong>процессоров текущего поколения и могут быть уверены, что <strong>NVIDIA</strong> в будущем будетвкладывать средства в разработку ещё более производительных решений.Продуктивность. Разработчики, ищущие доступ к вычислительной мощи <strong>графических</strong>процессоров <strong>NVIDIA</strong> могут теперь пользоваться стандартным языком программирования'C' для разработки приложений. <strong>CUDA</strong> предоставляет законченное решение дляразработчиков, которое интегрируется в программное обеспечение для CPU и GPU, чтобы


быстро получить доступ к новым возможностям и высокой оценке потребителей(возможно, они имели ввиду что-то другое. но получилось так).Масштабируемость. Приложения, разработанные с использованием технологии <strong>CUDA</strong>масштабируются в производительности и возможностях по всей линейке <strong>графических</strong>процессоров <strong>NVIDIA</strong>, <strong>на</strong>чи<strong>на</strong>я от интегрированных решений и заканчиваявысокопроизводительными профессио<strong>на</strong>льными графическими картами, использующимимножество <strong>графических</strong> процессоров. Производительность <strong>CUDA</strong> теперь фактическидоступ<strong>на</strong> в системах любого уровня от специальных вычислительных станций допотребительских продуктов.Разрабатывайте с <strong>CUDA</strong>Комплект разработки программного обеспечения <strong>CUDA</strong> (<strong>CUDA</strong> SDK) - это законченноерешение для разработчиков, использующих возможности <strong>графических</strong> процессоров длярешения задач общего <strong>на</strong>з<strong>на</strong>чения. SDK включает стандартные библиотеки FFT и BLAS (яне в курсе об этом), компилятор C для графического процессора <strong>NVIDIA</strong> и runtimeдрайвер.<strong>CUDA</strong> runtime-драйвер работающий совместно с самостоятельным драйвером,решающим задачи распределения <strong>на</strong>грузки OpenGL и MS DirectX. Технология <strong>CUDA</strong> вравной степени поддерживается операционными системами MS Windows XP (ага! вистане поддерживается) и Linux.Возможности технологии- Унификация программных и аппаратных решений для потоковых вычислений <strong>на</strong><strong>графических</strong> процессорах <strong>NVIDIA</strong> с поддержкой <strong>CUDA</strong>.- Графические процессоры с <strong>CUDA</strong> поддерживают кэш параллельных данных (ParallelData Cache) и менеджер исполняемых потоков (Thread Execution Manager) длявысокопроизводительных вычислений.- Стандартный язык программирования C для GPU.- Стандартные числовые библиотеки для FFT и BLAS.- Отдельный драйвер CUDА для вычислений.- Оптимизированный путь загрузки и выгрузки с CPU <strong>на</strong> GPU с <strong>CUDA</strong>.- <strong>CUDA</strong>-драйвер, работающий совместно с графическим драйвером.- Поддержка Linux и WinXP- Масштабируемость от высокопроизводительных профессио<strong>на</strong>льных <strong>графических</strong>решений до мабильных и интегрированных GPU.- Встроен<strong>на</strong>я поддержка multi-GPU для высоко"плотных" вычислений.- Поддержка аппаратной отладки и профилер для разработки и оптимизации программ.Материал взят со страницы (<strong>на</strong> англ. языке)Немного больше...Основу аппаратных средств <strong>CUDA</strong>-вычислителя образует потоковый процессор (SP,Streaming Processor), 32-битовое арифметико-логическое устройство которого ипредоставляет каждому потоку вычислительные возможности.Восемь SP, каждый со своим модулем регистровой памяти емкостью 32 KB,объединяются в потоковый мультипроцессор (SM, Streaming Multiprocessor) –вычислительную машину SIMD-архитектуры, имеющую собственные механизм выборкии декодирования команд, независимые кэши команд и данных (констант), диспетчерпотоков и блок памяти емкостью 16 KB, разделяемой между всеми восемью SP.Работающий <strong>на</strong> тактовой частоте 1,35 GHz, SM способен предоставлять более чем


семистам потокам вычислительную мощность порядка 20 GFLOPS. SP выполняет однуSIMD-команду за один машинный такт.Два SM, дополненные более высокоуровневой кэш-памятью команд и данных, образуюткластер обработки текстур (TPC, Texture Processing Cluster). И, <strong>на</strong>конец, из восьми TPCформируется собственно <strong>CUDA</strong>-вычислитель, – массив потоковых процессоров (SPA,Streaming Processor Array).Таким образом, в распоряжении <strong>CUDA</strong>-программиста имеется вычислитель<strong>на</strong>я система,пусть весьма слож<strong>на</strong>я из-за разнообразия адресных пространств и специфическихмеханизмов, но все же ос<strong>на</strong>щен<strong>на</strong>я 128 32-разрядными арифметико-логическимиустройствами, способными за один такт исполнять такие команды, как умножение с<strong>на</strong>коплением (обычно обоз<strong>на</strong>чаются MADD, смысл этой трехоперандной операциипонятен из псевдокода A=A+B*C). Потенциаль<strong>на</strong>я пиковая производительность такойсистемы – 346 GFLOPS. Это одновременно и немало, и не очень много, если учесть тотфакт, что пиковая производительность четырехъядерных процессоров класса Core 2 Duoсовсем немного не дотягивает до 100 GFLOPS.Маленький пример программ использующие <strong>CUDA</strong>Приведу пару примеров, софт возьму от одного из пользователей <strong>на</strong>шего форума, аименно Xserg, за что ему спасибо)Mini Release nv<strong>CUDA</strong>.exeXP необходимо установить последние драйверы ForceWare: 169.21MD5 хеши // Заточено <strong>на</strong> популярную GF8600GTПредваритель<strong>на</strong>я атака 2..5 символов (0x21..0x7f)Команд<strong>на</strong>я строка:// перебирает 0..9,a..znv<strong>CUDA</strong>.exe -f=mypas.txt -s=7 -e=7-f= файл с паролями до 50 шт. типа admin:9987d22788e810116a45109f2ea88648-s= <strong>на</strong>чальное количество символов в пароле 6 - by default-e= конечное количество символов в пароле 8 - by defaultНеобходимые библиотеки dll.rar (158кб.) // cudart.dll , cutil32.dllСобранный файл + Исходник nv<strong>CUDA</strong>.rar (82кб.)Mini Release nv<strong>CUDA</strong>sql.exeMySql хешиКоманд<strong>на</strong>я строка:nv<strong>CUDA</strong>sql.exe -f=mysqlpas.txt -s=4 -e=10 -sl=91 –bl=20-f= файл с паролями до 50 шт. типа hash:6cb1963d2018c3ea-s= <strong>на</strong>чальное количество символов в пароле 4 - by default


-e= конечное количество символов в пароле 10 - by default-sl= 25 , 35 , 71 , 91 <strong>на</strong>боры символов-bl=производительность видеокарты. (20 - 128)Собранный файл + Исходник ncCuda_mysql.rar (81кб.)Скорость перебора одного хеша 8 000 000 000 000 п/c. <strong>на</strong> GF8600GT

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!