Нужно ли обновлять драйвера видеокарты при Майнинге?
Но если вы собрали риг для добычи криптовалюты, то установка драйвера жизненно необходима, иначе оборудование будет зависать. Для достижения высокой производительности при добычи криптовалют необходимо использовать самые производительные драйвера, а также правильно конфигурировать операционную систему.
Интересные материалы:
Как часто нужно поливать клубнику? Как часто нужно заниматься на брусьях? Как часто нужно заниматься на гребном тренажере? Как часто обновляются данные в Пенсионном фонде? Как часто опрыскивать помидоры? Как часто пересматривается состав потребительской корзины? Как часто пересматриваются состав потребительской корзины? Как часто поливать баклажаны? Как часто поливать капусту в сентябре? Как часто поливать малину после посадки весной?
Вход в панель управления драйвером
Открыть средство конфигурирования «красных» GPU можно несколькими способами:
- Самый простой – воспользоваться контекстным меню «Рабочего стола»: щёлкните по нему правой кнопкой мыши (ПКМ) и выберите пункт «Настройки Radeon» / «AMD Catalyst Control Center».
- Следующий метод – меню «Пуск»: откройте его, затем найдите папку с нужным приложением и вызовите.
- Также можно воспользоваться системным треем – специальной областью в нижнем правом углу экрана, где находятся открытые фоновые приложения. Как правило, значок панели управления видеокартой выглядит следующим образом:
Для открытия главного меню настроек кликните по нему либо один раз правой, либо два левой кнопкой мыши.
- Следующий вариант – системный «Поиск». В Windows 10 надо щёлкнуть по кнопке или строке на панели задач и вписать туда запрос radeon или amd, нажать Enter и воспользоваться релевантным результатом.
- Последний способ, который стоит задействовать в крайнем случае – поиск и запуск с исполняемого файла. Для решения этой задачи откройте окно «Проводника», кликните левой кнопкой мыши по адресной строке, вставьте в него один из адресов ниже и нажмите элемент перехода:
- C:\Program Files\AMD\CNext\CCCSlim и C:\Program Files (x86)\AMD\CNext\CCCSlim – AMD Catalyst Control Center;
C:\Program Files\AMD\CNext\CNext – Настройки Radeon.
Далее найдите EXE-файл с именем CCC.exe или RadeonSettings.exe и запустите его для открытия нужной оснастки.
Что делать, если настройки Radeon не открываются
Если ни один из вышеприведённых шагов не решил задачу, предлагаем вам методы устранения этой проблемы. Первым делом стоит проверить, а установлены ли вообще драйвера для видеокарты – нередко причина именно в этом. Откройте «Диспетчер устройств», посредством уже упомянутой выше оснастки «Выполнить», только на этот раз нужная команда выглядит как devmgmt.msc.
Далее раскройте категорию «Видеоадаптеры» и проверьте, как именно обозначено ваше устройство AMD. Если надпись гласит «Базовый видеодрайвер Microsoft», это значит, что ПО для GPU не установлено.
Подробнее: Пример установки драйверов для видеокарты AMD
Если же видеокарта отображается как положено, но на значке присутствует жёлтый треугольник ошибки, кликните по ней ПКМ и выберите «Свойства».
Проверьте блок «Состояние» – в нём указывается непосредственная ошибка и её код обозначения. О проблемах с драйверами говорят коды 2 и 10, и в таком случае следует либо установить нужный софт, либо переустановить начисто.
Подробнее: Переустановка драйверов видеокарты
Если же код ошибки указан как 43, это значит, что устройство неисправно, и все попытки инсталлировать драйвера ни к чему не приведут.
Подробнее: Что делать с ошибкой 43 на видеокарте
Также нельзя исключать и программные причины – например, активность вирусного ПО, которое повредило драйвер. Разумеется, проблему можно устранить удалением и повторной инсталляцией, но желательно убрать и её первопричину.
Подробнее: Борьба с компьютерными вирусами
Мы рады, что смогли помочь Вам в решении проблемы. Помимо этой статьи, на сайте еще 12578 инструкций. Добавьте сайт Lumpics.ru в закладки (CTRL+D) и мы точно еще пригодимся вам. Отблагодарите автора, поделитесь статьей в социальных сетях.
Опишите, что у вас не получилось. Наши специалисты постараются ответить максимально быстро.
Полезные функции
Осталось только упомянуть некоторые функции, которые могут пригодиться в быту. CALresult result; // Получение статуса отдельного устройства CALdevicestatus status; result = calDeviceGetStatus( &status, device ); // Принудительное завершение всех выполняемых на GPU задач result = calCtxFlush( context ); // Получение информации о функции из ядра (после компиляции) CALfunc function; CALfuncInfo functionInfo; result = calModuleGetFuncInfo( &functionInfo, context, module, function ); /* Хоть эта функция и выглядит привлекательной, она не работала в моем случае (я пытался узнать максимальное количество потоков, с которым может быть запущено ядро) */ // Получить описание последней произошедшей ошибки из библиотеки aticalrt.dll const char* errorString = calGetErrorString(); // Получить описание последней произошедшей ошибки из библиотеки aticalcl.dll (компилятор) const char* errorString = calclGetErrorString();
Компиляция и загрузка ядра на GPU
«Смерть Кощея в игле, игла в яйце, яйцо в утке, утка в зайце, заяц в сундуке…»
Процесс загрузки ядра на GPU можно описать следующим образом: исходник (txt) компилируется в объектник (object), затем один или несколько объектников линкуются в образ (image), который после этого загружается в модуль GPU (module), а уже из модуля можно получить указатель на точку входа ядра (по этому указателю мы сможем запустить ядро на исполнение).
А теперь, как это реализуется:
const char* kernel; // здесь должен лежать исходный текст ядра // Узнаем, под какую GPU компилировать unsigned int deviceId = 0; // идентификатор GPU CALdeviceinfo deviceInfo; CALresult result = calDeviceGetInfo( &deviceInfo, deviceId ); // Компилируем исходник CALobject obj; result = calclCompile( &obj, CAL_LANGUAGE_IL, kernel, deviceInfo.target ); // Линкуем объектник в образ CALimage image; result = calclLink( &image, &obj, 1 ); // второй параметр — список объектников, третий — количество объектников // Объектник нам уже не понадобится, освобождаем его result = calclFreeObject( obj ); // Загружаем образ в модуль CALmodule module; result = calModuleLoad( &module, context, image ); // Получаем точку входа в ядро CALfunc function; result = calModuleGetEntry( &function, context, module, «main» );
Правило №9:
точка входа в ядро всегда одна, так как там только одна функция после линковки — функция «main».
То есть в отличие от Nvidia CUDA, в ядре AMD CAL может быть только одна глобальная функция «main».
Как вы могли заметить, компилятор может обработать только исходник, написанный на языке IL.
Загрузка образа в модуль объясняется тем, что образ нужно подгрузить в выделенный контекст GPU. Следовательно, описанный процесс компиляции нужно делать для каждой GPU (за исключением случая, когда 2 одинаковые GPU: достаточно один раз скомпилировать и слинковать, но все равно придется загрузить образ в модуль для каждой карточки).
Хочу обратить внимание на возможность линковки нескольких объектников. Может, кому-нибудь эта возможность пригодится. На мой взгляд ее можно применить в случае различной реализации одной и той же подфункции: эти реализации можно вынести в различные объектники, так как в AMD IL нет директив препроцессора наподобие #ifdef.
После того, как завершится выполнение ядра на GPU, надо будет освободить соответствующие ресурсы:
CALresult result = calclFreeImage( image ); result = calModuleUnload( context, module );
Инициализация драйвера
Правило №1:
перед началом работы с GPU вымыйте руки инициализируйте работу драйвера следующим вызовом: CALresult result = calInit();
Правило №2:
после работы с GPU не забываем смыть за собой завершить работу корректно. Это делается следующим вызовом: CALresult result = calShutdown(); Эти два вызова всегда должны идти в паре. Их (таких пар вызовов) может быть несколько в программе, но никогда не работайте с GPU вне этих вызовов: такое поведение может повлечь за собой
hardware exception
.
Межпоточая синхронизация
В отличие от Nvidia CUDA, вам не надо производить дополнительные действия с контекстом, если вы работаете с GPU из разных потоков. Но все же есть некоторые ограничения.
Правило №12:
все функции компилятора CAL
не являются
потоко-безопасными. В пределах одного приложения только один поток может работать с компилятором в один момент времени.
Правило №13:
все функции основной библиотеки CAL, работающие с конкретным контекстом/дескриптором устройства (context/device)
являются
потоко-безопасными. Все остальные функции
не являются
потоко-безопасными.
Правило №14:
только один поток приложения в один момент времени может работать с конкретным контекстом.
Копирование памяти
Получение прямого доступа к памяти
Если GPU поддерживает mapping
своей памяти (отображение адресов своей памяти в адресное пространство процесса), то мы можем получить указатель на эту память, а дальше работать с ней, как и с любой другой памятью: unsigned int pitch; unsigned char* mappedPointer; CALresult result = calResMap( (CALvoid**)&mappedPointer, &pitch, resource, 0 ); // последний параметр является флагами, но согласно документации, они не используются А после того, как мы закончим работу с памятью, необходимо освободить указатель: CALresult result = calResUnmap( resource );
Правило №7:
всегда помните, что при работе с памятью GPU нужно учитывать
выравнивание
. Это выравнивание характеризуется переменной
pitch
.
Правило №8:
pitch измеряется в
элементах
, а не в байтах.
Зачем нужно знать про это выравнивание? Дело в том, что в отличие от оперативной памяти, память GPU не всегда является непрерывной областью. Особенно это проявляется при работе с текстурами. Поясню сказанное на примере: если вы хотите работать с текстурой 100х100 элементов, а функция calResMap() вернула значение pitch равное 200, то это значит, что на самом деле GPU будет работать с текстурой 200х100, просто в каждой строке текстуры будут учитываться только первые 100 элементов.
Копирование в память GPU с учетом значения pitch можно организовать следующим образом:
unsigned int pitch; unsigned char* mappedPointer; unsigned char* dataBuffer; CALresult result = calResMap( (CALvoid**)&mappedPointer, &pitch, resource, 0 ); unsigned int width; unsigned int height; unsigned int elementSize = 16; if( pitch > width ) { for( uint index = 0; index < height; ++index ) { memcpy( mappedPointer + index * pitch * elementSize, dataBuffer + index * width * elementSize, width * elementSize ); } } else { memcpy( mappedPointer, dataBuffer, width * height * elementSize ); } Естественно, данные в dataBuffer должны быть подготовлены с учетом типа элемента. Но при этом помните, что элемент всегда имеет размер 16 байт. То есть для элемента формата CAL_FORMAT_UNSIGNED_INT16_2 его побайтовое представление в памяти будет следующим: // w — word, 16 бит // wi.j — i-й word, j-й байт // x — мусор [ w0.0 | w0.1 | x | x ][ w1.0 | w1.1 | x | x ][ x | x | x | x ][ x | x | x | x ]
Копирование данных между ресурсами
Копирование данных производится не напрямую между ресурсами, а между их отображенными на контекст значениями. Операция копирования является асинхронной, поэтому, чтобы узнать о завершении операции копирования, используется системный объект типа CALevent: CALresource inputResource; CALresource outputResource; CALmem inputResourceMem; CALmem outputResourceMem; // Отображаем ресурсы на контекст CALresult result = calCtxGetMem( &inputResourceMem, context, inputResource ); result = calCtxGetMem( &outputResourceMem, context, outputResource ); // Копируем данные CALevent syncEvent; result = calMemCopy( &syncEvent, context, inputResourceMem, outputResourceMem, 0 ); // последний параметр является флагами, но согласно документации, они не используются // Ждем завершения операции копирования while( calCtxIsEventDone( context, syncEvent ) == CAL_RESULT_PENDING );