Вычисления на GPU: мифы и реальность. Включение GPU ускорения Использование gpu вместо cpu

Ядер много не бывает…

Современные GPU – это монструозные шустрые бестии, способные пережевывать гигабайты данных. Однако человек хитер и, как бы не росли вычислительные мощности, придумывает задачи все сложнее и сложнее, так что приходит момент когда с грустью приходиться констатировать – нужна оптимизацию 🙁

В данной статье описаны основные понятия, для того чтобы было легче ориентироваться в теории gpu-оптимизации и базовые правила, для того чтобы к этим понятиям, приходилось обращаться по-реже.

Причины по которой GPU эффективны для работы с большими объемами данных, требующих обработки:

  • у них большие возможности по параллельному исполнению задач (много-много процессоров)
  • высокая пропускная способность у памяти

Пропускная способность памяти (memory bandwidth) – это сколько информации – бит или гигабайт – может может быть передано за единицу времени секунду или процессорный такт.

Одна из задач оптимизации – задействовать по максимуму пропускную способность – увеличить показатели throughput (в идеале она должна быть равна memory bandwidth).

Для улучшения использования пропускной способности:

  • увеличить объем информации – использовать пропускной канал на полную (например каждый поток работает с флоат4)
  • уменьшать латентность – задержку между операциями

Задержка (latency) – промежуток времени между моментами, когда контролер запросил конкретную ячейку памяти и тем моментом, когда данные стали доступны процессору для выполнения инструкций. На саму задержку мы никак повлиять не можем – эти ограничения присутствуют на аппаратном уровне. Именно за счет этой задержки процессор может одновременно обслуживать несколько потоков – пока поток А запросил выделить ему памяти, поток Б может что-то посчитать, а поток С ждать пока к нему придут запрошенные данные.

Как снизить задержку (latency) если используется синхронизация:

  • уменьшить число потоков в блоке
  • увеличить число групп-блоков

Использование ресурсов GPU на полную – GPU Occupancy

В высоколобых разговорах об оптимизации часто мелькает термин – gpu occupancy или kernel occupancy – он отражает эффективность использования ресурсов-мощностей видеокарты. Отдельно отмечу – если вы даже и используете все ресурсы – это отнюдь не значит что вы используете их правильно.

Вычислительные мощности GPU – это сотни процессоров жадных до вычислений, при создании программы – ядра (kernel) – на плечи программиста ложиться бремя распределения нагрузки на них. Ошибка может привести к тому, что большая часть этих драгоценных ресурсов может бесцельно простаивать. Сейчас я объясню почему. Начать придется издалека.

Напомню, что варп (warp в терминологии NVidia, wavefront – в терминологии AMD) – набор потоков которые одновременно выполняют одну и туже функцию-кернел на процессоре. Потоки, объединенные программистом в блоки разбиваются на варпы планировщиком потоков (отдельно для каждого мультипроцессора) – пока один варп работает, второй ждет обработки запросов к памяти и т.д. Если какие-то из потоков варпа все еще выполняют вычисления, а другие уже сделали все что могли – имеет место быть неэффективное использование вычислительного ресурса – в народе именуемое простаивание мощностей.

Каждая точка синхронизации, каждое ветвление логики может породить такую ситуацию простоя. Максимальная дивергенция (ветвление логики исполнения) зависит от размера варпа. Для GPU от NVidia – это 32, для AMD – 64.

Для того чтобы снизить простой мультипроцессора во время выполнения варпа:

  • минимизировать время ожидания барьеров
  • минимизировать расхождение логики выполнения в функции-кернеле

Для эффективного решения данной задачи имеет смысл разобраться – как же происходит формирование варпов (для случая с несколькими размерностями). На самом деле порядок простой – в первую очередь по X, потом по Y и, в последнюю очередь, Z.

ядро запускается с блоками размерностью 64×16, потоки разбиваются по варпам в порядке X, Y, Z – т.е. первые 64 элемента разбиваются на два варпа, потом вторые и т.д.

Ядро запускается с блоками размерностью 16×64. В первый варп добавляются первые и вторые 16 элементов, во второй варп – третьи и четвертые и т.д.

Как снижать дивергенцию (помните – ветвление – не всегда причина критичной потери производительности)

  • когда у смежных потоков разные пути исполнения – много условий и переходов по ним – искать пути ре-структуризации
  • искать не сбалансированную загрузку потоков и решительно ее удалять (это когда у нас мало того что есть условия, дак еще из-за этих условиях первый поток всегда что-то вычисляет, а пятый в это условие не попадает и простаивает)

Как использовать ресурсы GPU по максимуму

Ресурсы GPU, к сожалению, тоже имеют свои ограничения. И, строго говоря, перед запуском функции-кернела имеет смысл определить лимиты и при распределении нагрузки эти лимиты учесть. Почему это важно?

У видеокарт есть ограничения на общее число потоков, которое может выполнять один мультипроцессор, максимальное число потоков в одном блоке, максимальное число варпов на одном процессоре, ограничения на различные виды памяти и т.п. Всю эту информацию можно запросить как программно, через соответствующее API так и предварительно с помощью утилит из SDK. (Модули deviceQuery для устройств NVidia, CLInfo – для видеокарт AMD).

Общая практика:

  • число блоков/рабочих групп потоков должно быть кратно количеству потоковых процессоров
  • размер блока/рабочей группы должен быть кратен размеру варпа

При этом следует учитывать что абсолютный минимум – 3-4 варпа/вейфронта крутятся одновременно на каждом процессоре, мудрые гайды советуют исходить из соображения – не меньше семи вейфронатов. При этом – не забывать ограничения по железу!

В голове все эти детали держать быстро надоедает, потому для расчет gpu-occupancy NVidia предложила неожиданный инструмент – эксельный(!) калькулятор набитый макросами. Туда можно ввести информацию по максимальному числу потоков для SM, число регистров и размер общей (shared) памяти доступных на потоковом процессоре, и используемые параметры запуска функций – а он выдает в процентах эффективность использования ресурсов (и вы рвете на голове волосы осознавая что чтобы задействовать все ядра вам не хватает регистров).

информация по использованию:
http://docs.nvidia.com/cuda/cuda-c-best-practices-guide/#calculating-occupancy

GPU и операции с памятью

Видеокарты оптимизированы для 128-битных операций с памятью. Т.е. в идеале – каждая манипуляция с памятью, в идеале, должна изменять за раз 4 четырех-байтных значения. Основная неприятность для программиста заключается в том, что современные компиляторы для GPU не умеют оптимизировать такие вещи. Это приходится делать прямо в коде функции и, в среднем, приносит доли-процента по приросту производительности. Гораздо большее влияние на производительность имеет частота запросов к памяти.

Проблема обстоит в следующем – каждый запрос возвращает в ответ кусочек данных размером кратный 128 битам. А каждый поток использует лишь четверть его (в случае обычной четырех-байтовой переменной). Когда смежные потоки одновременно работают с данными расположенными последовательно в ячейках памяти – это снижает общее число обращений к памяти. Называется это явление – объединенные операции чтения и записи (coalesced access – good! both read and write ) – и при верной организации кода (strided access to contiguous chunk of memory – bad! ) может ощутимо улучшить производительность. При организации своего ядра – помните – смежный доступ – в пределах элементов одной строки памяти, работа с элементами столбца – это уже не так эффективно. Хотите больше деталей? мне понравилась вот эта pdf – или гуглите на предмет “memory coalescing techniques “.

Лидирующие позиции в номинации “узкое место” занимает другая операция с памятью – копирование данных из памяти хоста в гпу . Копирование происходит не абы как, а из специально выделенной драйвером и системой области памяти: при запросе на копирование данных – система сначала копирует туда эти данные, а уже потом заливает их в GPU. Скорость транспортировки данных ограничена пропускной способностью шины PCI Express xN (где N число линий передачи данных) через которые современные видеокарты общаются с хостом.

Однако, лишнее копирование медленной памяти на хосте – это порою неоправданные издержки. Выход – использовать так называемую pinned memory – специальным образом помеченную область памяти, так что операционная система не имеет возможности выполнять с ней какие либо операции (например – выгрузить в свап/переместить по своему усмотрению и т.п.). Передача данных с хоста на видеокарту осуществляется без участия операционной системы – асинхронно, через DMA (direct memory access).

И, на последок, еще немного про память. Разделяемая память на мультипроцессоре обычно организована в виде банков памяти содержащих 32 битные слова – данные. Число банков по доброй традиции варьируется от одного поколения GPU к другому – 16/32 Если каждый поток обращается за данными в отдельный банк – все хорошо. Иначе получается несколько запросов на чтение/запись к одному банку и мы получаем – конфликт (shared memory bank conflict ). Такие конфликтные обращения сериализуются и соответственно выполняются последовательно, а не параллельно. Если к одному банку обращаются все потоки – используется “широковещательный” ответ (broadcast ) и конфликта нет. Существует несколько способов эффективно бороться с конфликтами доступа, мне понравилось описание основных методик по избавлению от конфликтов доступа к банкам памяти – .

Как сделать математические операции еще быстрее? Помнить что:

  • вычисления двойной точности – это высокая нагрузка операции с fp64 >> fp32
  • константы вида 3.13 в коде, по умолчанию, интерпретируется как fp64 если явно не указывать 3.14f
  • для оптимизации математики не лишним будет справиться в гайдах – а нет ли каких флажков у компилятора
  • производители включают в свои SDK функции, которые используют особенности устройств для достижения производительности (часто – в ущерб переносимости)

Для разработчиков CUDA имеет смысл обратить пристальное внимание на концепцию cuda stream, позволяющих запускать сразу несколько функций-ядер на одному устройстве или совмещать асинхронное копирование данных с хоста на устройство во время выполнения функций. OpenCL, пока, такого функционала не предоставляет 🙁

Утиль для профилирования:

NVifia Visual Profiler – интересная утилитка, анализирует ядра как CUDA так и OpenCL.

P. S. В качестве более пространного руководства по оптимизации, могу порекомендовать гуглить всевозможные best practices guide для OpenCL и CUDA.

  • ,

Часто стал появляться вопрос: почему нет GPU ускорения в программе Adobe Media Encoder CC? А то что Adobe Media Encoder использует GPU ускорение, мы выяснили , а также отметили нюансы его использования . Также встречается утверждение: что в программе Adobe Media Encoder CC убрали поддержку GPU ускорения. Это ошибочное мнение и вытекает из того, что основная программа Adobe Premiere Pro CC теперь может работать без прописанной и рекомендованной видеокарты, а для включения GPU движка в Adobe Media Encoder CC, видеокарта должна быть обязательно прописана в документах: cuda_supported_cards или opencl_supported_cards. Если с чипсетами nVidia все понятно, просто берем имя чипсета и вписываем его в документ cuda_supported_cards. То при использовании видеокарт AMD прописывать надо не имя чипсета, а кодовое название ядра. Итак, давайте на практике проверим, как на ноутбуке ASUS N71JQ с дискретной графикой ATI Mobility Radeon HD 5730 включить GPU движок в Adobe Media Encoder CC. Технические данные графического адаптера ATI Mobility Radeon HD 5730 показываемые утилитой GPU-Z:

Запускаем программу Adobe Premiere Pro CC и включаем движок: Mercury Playback Engine GPU Acceleration (OpenCL).

Три DSLR видео на таймлайне, друг над другом, два из них, создают эффект картинка в картинке.

Ctrl+M, выбираем пресет Mpeg2-DVD, убираем черные полосы по бокам с помощью опции Scale To Fill. Включаем также повышеное качество для тестов без GPU: MRQ (Use Maximum Render Quality). Нажимаем на кнопку: Export. Загрузка процессора до 20% и оперативной памяти 2.56 Гбайт.


Загрузка GPU чипсета ATI Mobility Radeon HD 5730 составляет 97% и 352Мб бортовой видеопамяти. Ноутбук тестировался при работе от аккумулятора, поэтому графическое ядро / память работают на пониженных частотах: 375 / 810 МГц.

Итоговое время просчета: 1 минута и 55 секунд (вкл/откл. MRQ при использовании GPU движка, не влияет на итогове время просчета).
При установленной галке Use Maximum Render Quality теперь нажимаем на кнопку: Queue.


Тактовые частоты процессора при работе от аккумулятора: 930МГц.

Запускаем AMEEncodingLog и смотрим итоговое время просчета: 5 минут и 14 секунд .

Повторяем тест, но уже при снятой галке Use Maximum Render Quality, нажимаем на кнопку: Queue.

Итоговое время просчета: 1 минута и 17 секунд .

Теперь включим GPU движок в Adobe Media Encoder CC, запускаем программу Adobe Premiere Pro CC, нажимаем комбинацию клавиш: Ctrl + F12, выполняем Console > Console View и в поле Command вбиваем GPUSniffer, нажимаем Enter.


Выделяем и копируем имя в GPU Computation Info.

В директории программы Adobe Premiere Pro CC открываем документ opencl_supported_cards, и в алфавитном порядке вбиваем кодовое имя чипсета, Ctrl+S.

Нажимаем на кнопку: Queue, и получаем GPU ускорение просчета проекта Adobe Premiere Pro CC в Adobe Media Encoder CC.

Итоговое время: 1 минута и 55 секунд .

Подключаем ноутбук к розетке, и повторяем результаты просчетов. Queue, галка MRQ снята, без включения движка, загрузка оперативной памяти немного подросла:


Тактовые частоты процессора: 1.6ГГц при работе от розетки и включении режима: Высокая производительность.

Итоговое время: 46 секунд .

Включаем движок: Mercury Playback Engine GPU Acceleration (OpenCL), как видно от сети ноутбучная видеокарта работает на своих базовых частотах, загрузка GPU в Adobe Media Encoder CC достигает 95%.

Итоговое время просчета, снизилось с 1 минуты 55 секунд , до 1 минуты и 5 секунд .

*Для визуализации в Adobe Media Encoder CC теперь используется графический процессор (GPU). Поддерживаются стандарты CUDA и OpenCL. В Adobe Media Encoder CC, движок GPU используется для следующих процессов визуализации:
- Изменение четкости (от высокой к стандартной и наоборот).
- Фильтр временного кода.
- Преобразования формата пикселей.
- Расперемежение.
Если визуализируется проект Premiere Pro, в AME используются установки визуализации с GPU, заданные для этого проекта. При этом будут использованы все возможности визуализации с GPU, реализованные в Premiere Pro. Для визуализации проектов AME используется ограниченный набор возможностей визуализации с GPU. Если последовательность визуализируется с использованием оригинальной поддержки, применяется настройка GPU из AME, настройка проекта игнорируется. В этом случае все возможности визуализации с GPU Premiere Pro используются напрямую в AME. Если проект содержит VST сторонних производителей, используется настройка GPU проекта. Последовательность кодируется с помощью PProHeadless, как и в более ранних версиях AME. Если флажок Enable Native Premiere Pro Sequence Import (Разрешить импорт исходной последовательности Premiere Pro) снят, всегда используется PProHeadless и настройка GPU.

Читаем про скрытый раздел на системном диске ноутбука ASUS N71JQ.

Использование GPU для вычислений с помощью C++ AMP

До сих пор в обсуждении приемов параллельного программирования мы рассматривали только ядра процессора. Мы приобрели некоторые навыки распараллеливания программ по нескольким процессорам, синхронизации доступа к совместно используемым ресурсам и использования высокоскоростных примитивов синхронизации без применения блокировок.

Однако, существует еще один способ распараллеливания программ - графические процессоры (GPU) , обладающие большим числом ядер, чем даже высокопроизводительные процессоры. Ядра графических процессоров прекрасно подходят для реализации параллельных алгоритмов обработки данных, а большое их количество с лихвой окупает неудобства выполнения программ на них. В этой статье мы познакомимся с одним из способов выполнения программ на графическом процессоре, с использованием комплекта расширений языка C++ под названием C++ AMP .

Расширения C++ AMP основаны на языке C++ и именно поэтому в данной статье будут демонстрироваться примеры на языке C++. Однако, при умеренном использовании механизма взаимодействий в. NET, вы сможете использовать алгоритмы C++ AMP в своих программах для.NET. Но об этом мы поговорим в конце статьи.

Введение в C++ AMP

По сути, графический процессор является таким же процессором, как любые другие, но с особым набором инструкций, большим количеством ядер и своим протоколом доступа к памяти. Однако между современными графическими и обычными процессорами существуют большие отличия, и их понимание является залогом создания программ, эффективно использующих вычислительные мощности графического процессора.

    Современные графические процессоры обладают очень маленьким набором инструкций. Это подразумевает некоторые ограничения: отсутствие возможности вызова функций, ограниченный набор поддерживаемых типов данных, отсутствие библиотечных функций и другие. Некоторые операции, такие как условные переходы, могут стоить значительно дороже, чем аналогичные операции, выполняемые на обычных процессорах. Очевидно, что перенос больших объемов кода с процессора на графический процессор при таких условиях требует значительных усилий.

    Количество ядер в среднем графическом процессор значительно больше, чем в среднем обычном процессоре. Однако некоторые задачи оказываются слишком маленькими или не позволяют разбивать себя на достаточно большое количество частей, чтобы можно было извлечь выгоду от применения графического процессора.

    Поддержка синхронизации между ядрами графического процессора, выполняющими одну задачу, весьма скудна, и полностью отсутствует между ядрами графического процессора, выполняющими разные задачи. Это обстоятельство требует синхронизации графического процессора с обычным процессором.

Сразу возникает вопрос, какие задачи подходят для решения на графическом процессоре? Имейте в виду, что не всякий алгоритм подходит для выполнения на графическом процессоре. Например, графические процессоры не имеют доступа к устройствам ввода/вывода, поэтому у вас не получится повысить производительность программы, извлекающей ленты RSS из интернета, за счет использования графического процессора. Однако на графический процессор можно перенести многие вычислительные алгоритмы и обеспечить массовое их распараллеливание. Ниже приводится несколько примеров таких алгоритмов (этот список далеко не полон):

    увеличение и уменьшение резкости изображений, и другие преобразования;

    быстрое преобразование Фурье;

    транспонирование и умножение матриц;

    сортировка чисел;

    инверсия хеша «в лоб».

Отличным источником дополнительных примеров может служить блог Microsoft Native Concurrency , где приводятся фрагменты кода и пояснения к ним для различных алгоритмов, реализованных на C++ AMP.

C++ AMP - это фреймворк, входящий в состав Visual Studio 2012, дающий разработчикам на C++ простой способ выполнения вычислений на графическом процессоре и требующий лишь наличия драйвера DirectX 11. Корпорация Microsoft выпустила C++ AMP как открытую спецификацию , которую может реализовать любой производитель компиляторов.

Фреймворк C++ AMP позволяет выполнять код на графических ускорителях (accelerators) , являющихся вычислительными устройствами. С помощью драйвера DirectX 11 фреймворк C++ AMP динамически обнаруживает все ускорители. В состав C++ AMP входят также программный эмулятор ускорителя и эмулятор на базе обычного процессора, WARP, которые служит запасным вариантом в системах без графического процессора или с графическим процессором, но в отсутствие драйвера DirectX 11, и использует несколько ядер и инструкции SIMD.

А теперь приступим к исследованию алгоритма, который легко можно распараллелить для выполнения на графическом процессоре. Реализация ниже принимает два вектора одинаковой длины и вычисляет поточечный результат. Сложно представить что-либо более прямолинейное:

Void VectorAddExpPointwise(float* first, float* second, float* result, int length) { for (int i = 0; i < length; ++i) { result[i] = first[i] + exp(second[i]); } }

Чтобы распараллелить этот алгоритм на обычном процессоре, требуется разбить диапазон итераций на несколько поддиапазонов и запустить по одному потоку выполнения для каждого из них. Мы посвятили достаточно много времени в предыдущих статьях именно такому способу распараллеливания нашего первого примера поиска простых чисел - мы видели, как можно это сделать, создавая потоки вручную, передавая задания пулу потоков и используя Parallel.For и PLINQ для автоматического распараллеливания. Вспомните также, что при распараллеливании похожих алгоритмов на обычном процессоре мы особо заботились, чтобы не раздробить задачу на слишком мелкие задания.

Для графического процессора эти предупреждения не нужны. Графические процессоры имеют множество ядер, выполняющих потоки очень быстро, а стоимость переключения контекста значительно ниже, чем в обычных процессорах. Ниже приводится фрагмент, пытающийся использовать функцию parallel_for_each из фреймворка C++ AMP:

#include #include using namespace concurrency; void VectorAddExpPointwise(float* first, float* second, float* result, int length) { array_view avFirst (length, first); array_view avSecond(length, second); array_view avResult(length, result); avResult.discard_data(); parallel_for_each(avResult.extent, [=](index<1> i) restrict(amp) { avResult[i] = avFirst[i] + fast_math::exp(avSecond[i]); }); avResult.synchronize(); }

Теперь исследуем каждую часть кода отдельно. Сразу заметим, что общая форма главного цикла сохранилась, но первоначально использовавшийся цикл for был заменен вызовом функции parallel_for_each. В действительности, принцип преобразования цикла в вызов функции или метода для нас не нов - ранее уже демонстрировался такой прием с применением методов Parallel.For() и Parallel.ForEach() из библиотеки TPL.

Далее, входные данные (параметры first, second и result) обертываются экземплярами array_view . Класс array_view служит для обертывания данных, передаваемых графическому процессору (ускорителю). Его шаблонный параметр определяет тип данных и их размерность. Чтобы выполнить на графическом процессоре инструкции, обращающиеся к данным, первоначально обрабатываемым на обычном процессоре, кто-то или что-то должен позаботиться о копировании данных в графический процессор, потому что большинство современных графических карт являются отдельными устройствами с собственной памятью. Эту задачу решают экземпляры array_view - они обеспечивают копирование данных по требованию и только когда они действительно необходимы.

Когда графический процессор выполнит задание, данные копируются обратно. Создавая экземпляры array_view с аргументом типа const, мы гарантируем, что first и second будут скопированы в память графического процессора, но не будут копироваться обратно. Аналогично, вызывая discard_data() , мы исключаем копирование result из памяти обычного процессора в память ускорителя, но эти данные будут копироваться в обратном направлении.

Функция parallel_for_each принимает объект extent, определяющий форму обрабатываемых данных и функцию для применения к каждому элементу в объекте extent. В примере выше мы использовали лямбда-функцию, поддержка которых появилась в стандарте ISO C++2011 (C++11). Ключевое слово restrict (amp) поручает компилятору проверить возможность выполнения тела функции на графическом процессоре и отключает большую часть синтаксиса C++, который не может быть скомпилирован в инструкции графического процессора.

Параметр лямбда-функции, index<1> объекта, представляет одномерный индекс. Он должен соответствовать используемому объекту extent - если бы мы объявили объект extent двумерным (например, определив форму исходных данных в виде двумерной матрицы), индекс также должен был бы быть двумерным. Пример такой ситуации приводится чуть ниже.

Наконец, вызов метода synchronize() в конце метода VectorAddExpPointwise гарантирует копирование результатов вычислений из array_view avResult, произведенных графическим процессором, обратно в массив result.

На этом мы заканчиваем наше первое знакомство с миром C++ AMP, и теперь мы готовы к более подробным исследованиям, а так же к более интересным примерам, демонстрирующим выгоды от использования параллельных вычислений на графическом процессоре. Сложение векторов - не самый удачный алгоритм и не самый лучший кандидат для демонстрации использования графического процессора из-за больших накладных расходов на копирование данных. В следующем подразделе будут показаны два более интересных примера.

Умножение матриц

Первый «настоящий» пример, который мы рассмотрим, - умножение матриц. Для реализации мы возьмем простой кубический алгоритм умножения матриц, а не алгоритм Штрассена, имеющий время выполнения, близкое к кубическому ~O(n 2.807). Для двух матриц: матрицы A размером m x w и матрицы B размером w x n, следующая программа выполнит их умножение и вернет результат - матрицу C размером m x n:

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

Распараллелить эту реализацию можно несколькими способами, и при желании распараллелить этот код для выполнения на обычном процессоре правильным выбором был бы прием распараллеливания внешнего цикла. Однако графический процессор имеет достаточно большое количество ядер и распараллелив только внешний цикл, мы не сможем создать достаточное количество заданий, чтобы загрузить работой все ядра. Поэтому имеет смысл распараллелить два внешних цикла, оставив внутренний цикл нетронутым:

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

Эта реализация все еще близко напоминает последовательную реализацию умножения матриц и пример сложения векторов, приводившиеся выше, за исключением индекса, который теперь является двумерным и доступен во внутреннем цикле с применением оператора . Насколько эта версия быстрее последовательной альтернативы, выполняемой на обычном процессоре? Умножение двух матриц (целых чисел) размером 1024 х 1024 последовательная версия на обычном процессоре выполняет в среднем 7350 миллисекунд, тогда как версия для графического процессора - держитесь крепче - 50 миллисекунд, в 147 раз быстрее!

Моделирование движения частиц

Примеры решения задач на графическом процессоре, представленные выше, имеют очень простую реализацию внутреннего цикла. Понятно, что так будет не всегда. В блоге Native Concurrency, ссылка на который уже приводилась выше, демонстрируется пример моделирования гравитационных взаимодействий между частицами. Моделирование включает бесконечное количество шагов; на каждом шаге вычисляются новые значения элементов вектора ускорений для каждой частицы и затем определяются их новые координаты. Здесь распараллеливанию подвергается вектор частиц - при достаточно большом количестве частиц (от нескольких тысяч и выше) можно создать достаточно большое количество заданий, чтобы загрузить работой все ядра графического процессора.

Основу алгоритма составляет реализация определения результата взаимодействий между двумя частицами, как показано ниже, которую легко можно перенести на графический процессор:

// здесь float4 - это векторы с четырьмя элементами, // представляющие частицы, участвующие в операциях void bodybody_interaction (float4& acceleration, const float4 p1, const float4 p2) restrict(amp) { float4 dist = p2 – p1; // w здесь не используется float absDist = dist.x*dist.x + dist.y*dist.y + dist.z*dist.z; float invDist = 1.0f / sqrt(absDist); float invDistCube = invDist*invDist*invDist; acceleration + = dist*PARTICLE_MASS*invDistCube; }

Исходными данными на каждом шаге моделирования является массив с координатами и скоростями движения частиц, а в результате вычислений создается новый массив с координатами и скоростями частиц:

Struct particle { float4 position, velocity; // реализации конструктора, конструктора копирования и // оператора = с restrict(amp) опущены для экономии места }; void simulation_step(array & previous, array & next, int bodies) { extent <1> ext(bodies); parallel_for_each (ext, [&](index <1> idx) restrict(amp) { particle p = previous; float4 acceleration(0, 0, 0, 0); for (int body = 0; body < bodies; ++body) { bodybody_interaction (acceleration, p.position, previous.position); } p.velocity + = acceleration*DELTA_TIME; p.position + = p.velocity*DELTA_TIME; next = p; }); }

С привлечением соответствующего графического интерфейса, моделирование может оказаться очень интересным. Полный пример, представленный командой разработчиков C++ AMP, можно найти в блоге Native Concurrency. На моей системе с процессором Intel Core i7 и видеокартой Geforce GT 740M, моделирование движения 10 000 частиц выполняется со скоростью ~2.5 кадра в секунду (шагов в секунду) с использованием последовательной версии, выполняющейся на обычном процессоре, и 160 кадров в секунду с использованием оптимизированной версии, выполняющейся на графическом процессоре - огромное увеличение производительности.

Прежде чем завершить этот раздел, необходимо рассказать еще об одной важной особенности фреймворка C++ AMP, которая может еще больше повысить производительность кода, выполняемого на графическом процессоре. Графические процессоры поддерживают программируемый кеш данных (часто называемый разделяемой памятью (shared memory) ). Значения, хранящиеся в этом кеше, совместно используются всеми потоками выполнения в одной мозаике (tile). Благодаря мозаичной организации памяти, программы на основе фреймворка C++ AMP могут читать данные из памяти графической карты в разделяемую память мозаики и затем обращаться к ним из нескольких потоков выполнения без повторного извлечения этих данных из памяти графической карты. Доступ к разделяемой памяти мозаики выполняется примерно в 10 раз быстрее, чем к памяти графической карты. Иными словами, у вас есть причины продолжить чтение.

Чтобы обеспечить выполнение мозаичной версии параллельного цикла, методу parallel_for_each передается домен tiled_extent , который делит многомерный объект extent на многомерные фрагменты мозаики, и лямбда-параметр tiled_index, определяющий глобальный и локальный идентификатор потока внутри мозаики. Например, матрицу 16x16 можно разделить на фрагменты мозаики размером 2x2 (как показано на рисунке ниже) и затем передать функции parallel_for_each:

Extent <2> matrix(16,16); tiled_extent <2,2> tiledMatrix = matrix.tile <2,2> (); parallel_for_each (tiledMatrix, [=](tiled_index <2,2> idx) restrict(amp) { // ... });

Каждый из четырех потоков выполнения, принадлежащих одной и той же мозаике, могут совместно использовать данные, хранящиеся в блоке.

При выполнении операций с матрицами, в ядре графического процессора, взамен стандартного индекса index<2>, как в примерах выше, можно использовать idx.global . Грамотное использование локальной мозаичной памяти и локальных индексов может обеспечить существенный прирост производительности. Чтобы объявить мозаичную память, разделяемую всеми потоками выполнения в одной мозаике, локальные переменные можно объявить со спецификатором tile_static.

На практике часто используется прием объявления разделяемой памяти и инициализации отдельных ее блоков в разных потоках выполнения:

Parallel_for_each(tiledMatrix, [=](tiled_index <2,2> idx) restrict(amp) { // 32 байта совместно используются всеми потоками в блоке tile_static int local; // присвоить значение элементу для этого потока выполнения local = 42; });

Очевидно, что какие-либо выгоды от использования разделяемой памяти можно получить только в случае синхронизации доступа к этой памяти; то есть, потоки не должны обращаться к памяти, пока она не будет инициализирована одним из них. Синхронизация потоков в мозаике выполняется с помощью объектов tile_barrier (напоминающего класс Barrier из библиотеки TPL) - они смогут продолжить выполнение только после вызова метода tile_barrier.Wait(), который вернет управление только когда все потоки вызовут tile_barrier.Wait. Например:

Parallel_for_each (tiledMatrix, (tiled_index <2,2> idx) restrict(amp) { // 32 байта совместно используются всеми потоками в блоке tile_static int local; // присвоить значение элементу для этого потока выполнения local = 42; // idx.barrier - экземпляр tile_barrier idx.barrier.wait(); // Теперь этот поток может обращаться к массиву "local", // используя индексы других потоков выполнения! });

Теперь самое время воплотить полученные знания в конкретный пример. Вернемся к реализации умножения матриц, выполненной без применения мозаичной организации памяти, и добавим в него описываемую оптимизацию. Допустим, что размер матрицы кратен числу 256 - это позволит нам работать с блоками 16 х 16. Природа матриц допускает возможность поблочного их умножения, и мы можем воспользоваться этой особенностью (фактически, деление матриц на блоки является типичной оптимизацией алгоритма умножения матриц, обеспечивающей более эффективное использование кеша процессора).

Суть этого приема сводится к следующему. Чтобы найти C i,j (элемент в строке i и в столбце j в матрице результата), нужно вычислить скалярное произведение между A i,* (i-я строка первой матрицы) и B *,j (j-й столбец во второй матрице). Однако, это эквивалентно вычислению частичных скалярных произведений строки и столбца с последующим суммированием результатов. Мы можем использовать это обстоятельство для преобразования алгоритма умножения матриц в мозаичную версию:

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

Суть описываемой оптимизации в том, что каждый поток в мозаике (для блока 16 х 16 создается 256 потоков) инициализирует свой элемент в 16 х 16 локальных копиях фрагментов исходных матриц A и B. Каждому потоку в мозаике требуется только одна строка и один столбец из этих блоков, но все потоки вместе будут обращаться к каждой строке и к каждому столбцу по 16 раз. Такой подход существенно снижает количество обращений к основной памяти.

Чтобы вычислить элемент (i,j) в матрице результата, алгоритму требуется полная i-я строка первой матрицы и j-й столбец второй матрицы. Когда потоки мозаике 16x16, представленные на диаграмме и k=0, заштрихованные области в первой и второй матрицах будут прочитаны в разделяемую память. Поток выполнения, вычисляющий элемент (i,j) в матрице результата, вычислит частичное скалярное произведение первых k элементов из i-й строки и j-го столбца исходных матриц.

В данном примере применение мозаичной организации обеспечивает огромный прирост производительности. Мозаичная версия умножения матриц выполняется намного быстрее простой версии и занимает примерно 17 миллисекунд (для тех же исходных матриц размером 1024 х 1024), что в 430 быстрее версии, выполняемой на обычном процессоре!

Прежде чем закончить обсуждение фреймворка C++ AMP, нам хотелось бы упомянуть инструменты (в Visual Studio), имеющиеся в распоряжении разработчиков. Visual Studio 2012 предлагает отладчик для графического процессора (GPU), позволяющий устанавливать контрольные точки, исследовать стек вызовов, читать и изменять значения локальных переменных (некоторые ускорители поддерживают отладку для GPU непосредственно; для других Visual Studio использует программный симулятор), и профилировщик, дающий возможность оценивать выгоды, получаемые приложением от распараллеливания операций с применением графического процессора. За дополнительной информацией о возможностях отладки в Visual Studio обращайтесь к статье «Пошаговое руководство. Отладка приложения C++ AMP» на сайте MSDN.

Альтернативы вычислений на графическом процессоре в.NET

До сих пор в этой статье демонстрировались примеры только на языке C++, тем не менее, есть несколько способов использовать мощь графического процессора в управляемых приложениях. Один из способов - использовать инструменты взаимодействий, позволяющие переложить работу с ядрами графического процессора на низкоуровневые компоненты C++. Это решение отлично подходит для тех, кто желает использовать фреймворк C++ AMP или имеет возможность использовать уже готовые компоненты C++ AMP в управляемых приложениях.

Другой способ - использовать библиотеку, непосредственно работающую с графическим процессором из управляемого кода. В настоящее время существует несколько таких библиотек. Например, GPU.NET и CUDAfy.NET (обе являются коммерческими предложениями). Ниже приводится пример из репозитория GPU.NET GitHub, демонстрирующий реализацию скалярного произведения двух векторов:

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

Я придерживаюсь мнения, что гораздо проще и эффективнее освоить расширение языка (на основе C++ AMP), чем пытаться организовывать взаимодействия на уровне библиотек или вносить существенные изменения в язык IL.

Итак, после того как мы рассмотрели возможности параллельного программирования в.NET и использованием GPU наверняка ни у кого не осталось сомнений, что организация параллельных вычислений является важным способом повышения производительности. Во многих серверах и рабочих станциях по всему миру остаются неиспользуемыми бесценные вычислительные мощности обычных и графических процессоров, потому что приложения просто не задействуют их.

Библиотека Task Parallel Library дает нам уникальную возможность включить в работу все имеющиеся ядра центрального процессора, хотя при этом и придется решать некоторые интереснейшие проблемы синхронизации, чрезмерного дробления задач и неравного распределения работы между потоками выполнения.

Фреймворк C++ AMP и другие многоцелевые библиотеки организации параллельных вычислений на графическом процессоре с успехом можно использовать для распараллеливания вычислений между сотнями ядер графического процессора. Наконец, имеется, неисследованная ранее, возможность получить прирост производительности от применения облачных технологий распределенных вычислений, превратившихся в последнее время в одно из основных направлений развития информационных технологий.

Сегодня особенно активно обсуждается и многие пользователи интересуются, с чего начать добычу монет и как это вообще происходит. Популярность этой индустрии уже оказала ощутимое влияние на рынок графических процессоров и мощная видеокарта у многих уже давно ассоциируется не с требовательными играми, а с криптофермами. В данной статье мы расскажем о том, как организовать весь этот процесс с нуля и начать майнить на собственной ферме, что для этого использовать и почему невозможен .

Что такое майнинг на видеокарте

Майнинг на видеокарте - это процесс добычи криптовалюты с помощью графических процессоров (GPU). Для этого используют мощную видеокарту в домашнем компьютере или специально собранную ферму из нескольких устройств в одной системе. Если вас интересует, почему для этого процесса используются именно GPU, то ответ весьма прост. Всё дело в том, что видеокарты изначально разрабатываются для обработки большого количества данных путём произведения однотипных операций, как в случае с обработкой видео. Такая же картина наблюдается и в майнинге криптовалюты, ведь тут процесс хэширования столь же однотипен.

Для майнинга используются полноценные дискретные видеокарты. Ноутбуки или интегрированный в процессор чипы не используются. В сети также встречаются статьи про майнинг на внешней видеокарте, но это также работает не во всех случаях и является не лучшим решением.

Какие видеокарты подойдут для майнинга

Итак, что касается выбора видеокарты, то здесь обычной практикой является приобретение AMD rx 470, rx 480, rx 570, rx 580 или Нвидиа 1060, 1070, 1080 ti. Также подойдут, но не принесут большой прибыли, видеокарты типа r9 280x, r9 290, 1050, 1060. Совершенно точно не принесёт прибыли майнинг на слабой видеокарте вроде geforce gtx 460, gts 450, gtx 550ti. Если говорить о памяти, то брать лучше от 2 гб. Может оказаться недостаточно даже 1 гб, не говоря уже о 512 мб. Если говорить про майнинг на профессиональной видеокарте, то приносит он примерно столько же, сколько и обычные или даже меньше. С учётом стоимости таких ВК - это невыгодно, но добывать с их помощью можно, если они уже есть у вас в наличии.

Стоит также отметить, что все видеокарты могут получить прирост производительности благодаря разблокировке значений, которые заложил производитель. Такой процесс называется разгон. Однако это небезопасно, приводит к потере гарантии и карта может выйти из строя, например, начав показывать артефакты. Разгонять видеокарты можно, но нужно ознакомиться с материалами по данной теме и действовать с осторожностью. Не стоит пытаться сразу установить все значения на максимум, а ещё лучше найти в интернете примеры удачных настроек разгона именно для вашей видеокарты.

Самые популярные видеокарты для майнинга 2020

Ниже приведено сравнение видеокарт. Таблица содержит самых популярных устройств и их максимальное энергопотребление. Нужно сказать, что эти показатели могут варьироваться в зависимости от конкретной модели видеокарты, её производителя, используемой памяти и некоторых других характеристик. Писать об устаревших показателях, таких как майнинг лайткоин на видеокарте, нет смысла, поэтому рассматриваются только три самых популярных алгоритма для ферм на видеокартах.

Видеокарта Ethash Equihash CryptoNight Энергопотребление
AMD Radeon R9 280x 11 MH/s 290 H/s 490 H/s 230W
AMD Radeon RX 470 26 MH/s 260 H/s 660 H/s 120W
AMD Radeon RX 480 29.5 MH/s 290 H/s 730 H/s 135W
AMD Radeon RX 570 27.9 MH/s 260 H/s 700 H/s 120W
AMD Radeon RX 580 30.2 MH/s 290 H/s 690 H/s 135W
Nvidia GeForce GTX 750 TI 0.5 MH/s 75 H/s 250 H/s 55W
Nvidia GeForce GTX 1050 TI 13.9 MH/s 180 H/s 300 H/s 75W
Nvidia GeForce GTX 1060 22.5 MH/s 270 H/s 430 H/s 90W
Nvidia GeForce GTX 1070 30 MH/s 430 H/s 630 H/s 120W
Nvidia GeForce GTX 1070 TI 30.5 MH/s 470 H/s 630 H/s 135W
Nvidia GeForce GTX 1080 23.3 MH/s 550 H/s 580 H/s 140W
Nvidia GeForce GTX 1080 TI 35 MH/s 685 H/s 830 H/s 190W

Возможен ли майнинг на одной видеокарте?

Если у вас нет желания собирать полноценную ферму из множества GPU или вы просто хотите опробовать этот процесс на домашнем компьютере, то можно майнить и одной видеокартой. Никаких отличий нет и вообще количество устройств в системе не важно. Более того, вы можете установить устройства с разными чипами или даже от разных производителей. Потребуется лишь запустить параллельно две программы для чипов разных компаний. Напомним ещё раз, что майнинг на интегрированной видеокарте не производится.

Какие криптовалюты можно майнить на видеокартах

Майнить на GPU можно любую криптовалюту, но следует понимать, что производительность на разных будет отличаться на одной и той же карточке. Более старые алгоритмы уже плохо подходят для видеопроцессоров и не принесут никакой прибыли. Происходит это из-за появления на рынке новых устройств - так называемых . Они являются куда более производительными и значительно повышают сложность сети, однако их стоимость высока и исчисляется тысячами долларов. Поэтому добыча монет на SHA-256 (Биткоин) или Scrypt (Litecoin, Dogecoin) в домашних условиях - это плохая идея в 2018-ом году.

Кроме LTC и DOGE, ASICи сделали невозможной добычу Bitcoin (BTC), Dash и других валют. Куда лучшим выбором станут криптовалюты, которые используют защищенные от ASIC-ов алгоритмы. Так, например, с помощью GPU получится добывать монеты на алгоритмах CryptoNight (Карбованец, Монеро, Electroneum, Bytecoin), Equihash (ZCash, Hush, Bitcoin Gold) и Ethash (Ethereum, Ethereum Classic). Список далеко не полный и постоянно появляются новые проекты на этих алгоритмах. Среди них встречаются как форки более популярных монет, так и совершенно новые разработки. Изредка даже появляются новые алгоритмы, которые предназначены для решения определённых задач и могут использовать различное оборудование. Ниже будет рассказано о том, как узнать хешрейт видеокарты.

Что нужно для майнинга на видеокарте

Ниже приведён список того, что вам понадобится для создания фермы:

  • Сами видеокарты. Выбор конкретных моделей зависит от вашего бюджета или того, что уже имеется в наличии. Конечно, старые устройства на AGP не подойдут, но можно использовать любую карту среднего или топового класса последних годов. Выше вы можете вернуться к таблице производительности видеокарт, которая позволит сделать подходящий выбор.
  • Компьютер для их установки. Не обязательно использовать топовое железо и делать ферму на базе высокопроизводительных комплектующих. Достаточно будет какого-нибудь старого AMD Athlon, нескольких гигабайт оперативной памяти и жесткого диска для установки операционной системы и нужных программ. Важна также материнская плата. Она должна иметь достаточное для вашей фермы количество PCI слотов. Существуют специальные версии для майнеров, которые содержат 6-8 слотов и в определённых случаях выгодней использовать их, чем собирать несколько ПК. Особое внимание стоит уделять лишь блоку питания, ведь система будет работать под высокой нагрузкой круглые сутки. Брать БП нужно обязательно с запасом мощности и желательно наличие сертификатов 80 Plus. Возможно также соединение двух блоков в один с помощью специальных переходников, но такое решение вызывает в интернете споры. Корпус лучше не использовать вовсе. Для лучшего охлаждения рекомендуется сделать или купить специальный стенд. Видеокарты в таком случае выносятся с помощью специальных переходников, которые называются райзеры. Приобрести их можно в профильных магазинах или на алиэкспрессе.
  • Хорошо проветриваемое сухое помещение. Размещать ферму стоит в нежилой комнате, а лучше вообще в отдельном помещении. Это позволит избавиться от дискомфорта, который возникает из-за шумной работы систем охлаждения и теплоотдачи. Если такой возможности нет, то следует выбирать видеокарты с максимально тихой системой охлаждения. Узнать о ней подробней вы сможете из обзоров в интернете, например, на YouTube. Следует также подумать о циркуляции воздуха и вентилируемости, чтобы максимально снизить температуру.
  • Программа майнер. GPU майнинг происходит с помощью специального , которое может быть найдено в интернете. Для производителей ATI Radeon и Nvidia используется разный софт. Это же касается и разных алгоритмов.
  • Обслуживание оборудования. Это очень важный пункт, так как не все понимают, что майнинг ферма требует постоянного ухода. Пользователю нужно следить за температурой, менять термопасту и очищать СО от пыли. Следует также помнить о технике безопасности и регулярно проверять исправность системы.

Как настроить майнинг на видеокарте с нуля

В данном разделе нами будет рассмотрен весь процесс добычи от выбора валюты до вывода средств. Следует отметить, что весь этот процесс может несколько отличаться для различных пулов, программ и чипов.

Как выбрать видеокарту для майнинга

Мы рекомендуем вам ознакомиться с таблицей, которая представлена выше и с разделом о подсчёте потенциального заработка. Это позволит рассчитать примерный доход и определиться с тем, какое железо вам больше по карману, а также разобраться со сроками окупаемости вложений. Не стоит также забывать о совместимости разъёмов питания видеокарты и блока питания. Если используются разные, то следует заранее обзавестись соответствующими переходниками. Всё это легко покупается в китайских интернет магазинах за копейки или у местных продавцов с некоторой наценкой.

Выбираем криптовалюту

Теперь важно определиться с тем, какая монета вас интересует и каких целей вы хотите достичь. Если вас интересует заработок в реальном времени, то стоит выбирать валюты с наибольшим профитом на данный момент и продавать их сразу после получения. Можно также майнить самые популярные монеты и держать их до тех пор, пока не произойдёт скачок цены. Есть также, своего рода, стратегический подход, когда выбирается малоизвестная, но перспективная на ваш взгляд валюта и вы вкладываете мощности в неё, в надежде, что в будущем стоимость значительно возрастёт.

Выбираем пул для майнинга

Также имеют некоторые отличия. Некоторые из них требуют регистрации, а некоторым достаточно лишь адреса вашего кошелька для начала работы. Первые обычно хранят заработанные вами средства до достижения минимальной для выплаты суммы, либо в ожидании вывода вами денег в ручном режиме. Хорошим примером такого пула является Suprnova.cc. Там предлагается множество криптовалют и для работы в каждом из пулов достаточно лишь раз зарегистрироваться на сайте. Сервис прост в настройке и хорошо подойдёт новичкам.

Подобную упрощённую систему предлагает и сайт Minergate. Ну а если вы не хотите регистрироваться на каком-то сайте и хранить там заработанные средства, то вам следует выбрать какой-нибудь пул в официальной теме интересующей вас монеты на форуме BitcoinTalk. Простые пулы требуют лишь указания адреса для начисления крипты и в дальнейшем с помощью адреса можно будет узнавать статистику добычи.

Создаем криптовалютный кошелек

Данный пункт не нужен вам, если используете пул, который требует регистрацию и имеет встроенный кошелёк. Если же вы хотите получать выплаты автоматически себе на кошелёк, то попробуйте почитать о создании кошелька в статье о соответствующей монете. Данный процесс может существенно отличаться для разных проектов.

Можно также просто указывать адрес вашего кошелька на какой-то из бирж, но следует отметить, что не все обменные платформы принимают транзакции с пулов. Наилучшим вариантом будет создания кошелька непосредственно на вашем компьютере, но если вы работаете с большим количеством валют, то хранение всех блокчейнов будет неудобно. В таком случае стоит поискать надёжные онлайн кошельки, либо облегчённые версии, которые не требуют загрузки всей цепи блоков.

Выбираем и устанавливаем программу для майнинга

Выбор программы для добычи крипты зависит от выбранной монеты и её алгоритма. Наверное, все разработчики такого ПО имеют темы на BitcoinTalks, где можно найти ссылки на скачивание и информацию о том, как происходят настройка и запуск. Почти все эти программы имеют версии как для Виндовс, так и для Линукс. Большинство таких майнеров бесплатные, но некоторый процент времени они используют для подключения к пулу разработчика. Это своего рода комиссия за использование программного обеспечения. В некоторых случаях её можно отключить, но это приводит к ограничениям функционала.

Настройка программы заключается в том, что вы указываете пул для майнинга, адрес кошелька или логин, пароль (если есть) и другие опции. Рекомендуется, например, выставлять максимальный лимит температуры, при достижении которого ферма отключится, чтобы не вредить видеокартам. Регулируется скорость вентиляторов системы охлаждения и другие более тонкие настройки, которые вряд ли будут использоваться новичками.

Если вы не знаете, какое ПО выбрать, посмотрите наш материал, посвященный либо изучите инструкции на сайте пула. Обычно там всегда есть раздел, который посвящён началу работы. Он содержит перечень программ, которые можно использовать и конфигурации для .bat файлов. С его помощью можно быстро разобраться с настройкой и начать майнинг на дискретной видеокарте. Можно сразу создать батники для всех валют, с которыми вы хотите работать, чтобы в дальнейшем было удобнее переключаться между ними.

Запускаем майнинг и следим за статистикой

После запуска .bat файла с настройками вы увидите консольное окно, куда будет выводиться лог происходящего. Его также можно будет найти в папке с запускаемым файлом. В консоли вы можете ознакомиться с текущими показателем хешрейта и температурой карты. Вызывать актуальные данные обычно позволяют горячие клавиши.

Вы также сможете увидеть, если устройство не находит хэши. В таком случае будет выведено предупреждение. Случается это, когда что-то настроено неправильно, выбрано неподходящее для монеты программное обеспечение или ГПУ не функционирует должным образом. Многие майнеры также используют средства для удалённого доступа к ПК, чтобы следить за работой фермы, когда они находятся не там, где она установлена.

Выводим криптовалюту

Если вы используете пулы вроде Suprnova, то все средства просто накапливаются на вашем аккаунте и вы можете вывести их в любой момент. Остальные пулы чаще всего используют систему, когда средства начисляются автоматически на указанный кошелёк после получения минимальной суммы вывода. Узнать о том, сколько вы заработали, обычно можно на сайте пула. Требуется лишь указать адрес вашего кошелька или залогиниться в личный кабинет.

Сколько можно заработать?

Сумма, которую вы можете заработать, зависит от ситуации на рынке и, конечно, общего хешрейта вашей фермы. Важно также то, какую стратегию вы выберите. Необязательно продавать всё добытое сразу. Можно, например, подождать скачка курса намайненной монеты и получить в разы больше профита. Однако всё не так однозначно и предугадать дальнейшее развитие событий бывает просто нереально.

Окупаемость видеокарт

Подсчитать окупаемость поможет специальный онлайн калькулятор. В интернете их много, но мы рассмотрим этот процесс на примере сервиса WhatToMine . Он позволяет получать данные о текущем профите, основываясь на данных вашей фермы. Нужно только выбрать видеокарты, которые есть у вас в наличии, а потом добавить стоимость электроэнергии в вашем регионе. Сайт посчитает сколько вы можете заработать за сутки.

Следует понимать, что учитывается лишь текущее положение дел на рынке и ситуация может измениться в любой момент. Курс может упасть или подняться, сложность майнинга станет другой или появятся новые проекты. Так, например, может прекратиться добыча эфира в связи с возможным переходом сети на . Если прекратиться майнинг эфириума, то фермам нужно будет куда то направить свободные мощности, например, в майнинг ZCash на GPU, что повлияет на курс этой монеты. Подобных сценариев на рынке множество и важно понимать, что сегодняшняя картина может не сохраниться на протяжении всего срока окупаемости оборудования.

Одной из наиболее скрытых функций, в недавнем обновлении Windows 10, является возможность проверить, какие приложения используют ваш графический процессор (GPU). Если вы когда-либо открывали диспетчер задач, то наверняка смотрели на использование вашего ЦП, чтобы узнать, какие приложения наиболее грузят ЦП. В последних обновлениях добавлена ​​аналогичная функция, но для графических процессоров GPU. Это помогает понять, насколько интенсивным является ваше программное обеспечение и игры на вашем графическом процессоре, не загружая программное обеспечение сторонних разработчиков. Есть и еще одна интересная функция, которая помогает разгрузить ваш ЦП на GPU. Рекомендую почитать, как выбрать .

Почему у меня нет GPU в диспетчере задач?

К сожалению, не все видеокарты смогут предоставить системе Windows статистику, необходимую для чтения графического процессора. Чтобы убедиться, вы можете быстро использовать инструмент диагностики DirectX для проверки этой технологии.

  1. Нажмите "Пуск " и в поиске напишите dxdiag для запуска средства диагностики DirectX.
  2. Перейдите во вкладку "Экран", справа в графе "драйверы " у вас должна быть модель WDDM больше 2.0 версии для использования GPU графы в диспетчере задач.

Включить графу GPU в диспетчере задач

Чтобы увидеть использование графического процессора для каждого приложения, вам нужно открыть диспетчер задач.

  • Нажмите сочетание кнопок Ctrl + Shift + Esc , чтобы открыть диспетчер задач.
  • Нажмите правой кнопкой мыши в диспетчере задач на поле пустое "Имя" и отметьте из выпадающего меню GPU. Вы также можете отметить Ядро графического процессора , чтобы видеть, какие программы используют его.
  • Теперь в диспетчере задач, справа видна графа GPU и ядро графического процессора.


Просмотр общей производительности графического процессора

Вы можете отслеживать общее использование GPU, чтобы следить за ним при больших нагрузках и анализировать. В этом случае вы можете увидеть все, что вам нужно, на вкладке "Производительность ", выбрав графический процессор.


Каждый элемент графического процессора разбивается на отдельные графики, чтобы дать вам еще больше информации о том, как используется ваш GPU. Если вы хотите изменить отображаемые графики, вы можете щелкнуть маленькую стрелку рядом с названием каждой задачи. На этом экране также отображается версия вашего драйвера и дата, что является хорошей альтернативой использованию DXDiag или диспетчера устройств.