Новичок
Профиль
Группа: Участник
Сообщений: 9
Регистрация: 8.11.2011
Репутация: нет Всего: 3
|
Что-то похожее делал. Тут в соседней ветке форума привёл свежий работающий пример ( второе сообщение): http://forum.vingrad.ru/forum/topic-386830...hi-bit-gpu.htmlРаботает пока только для видеокарт NVIDIA и только при компиляции в Delphi под Win64 Но! Здесь загрузка GPU всеми процессами системы. Загрузку именно моим процессом - не знаю пока, как найти... Может, для NVIDIA по крайней мере, что-то подобное есть - http://docs.nvidia.com/deploy/nvml-api/index.html---- Возможно, эта функция полезна будет: nvmlDeviceGetComputeRunningProcesses(стр.108 здесь : https://docs.nvidia.com/deploy/pdf/NVML_API...rence_Guide.pdf ) или эта: nvmlDeviceGetProcessUtilization (там же, стр.166) ----- или вот, структура похожая: http://docs.nvidia.com/deploy/nvml-api/str...zationSample__tК сожалению, это работает только для "продвинутых" карт NVIDIA, а как дело обстоит с AMD - вообще пока не разобрался. Можно ли вообще найти загрузку потокового процессора конкретным процессом в системе? Не знаю... Не видел подобного у готовых утилит. +++++++++++++++++++Добавка от 5 янв.2018.Уже разобрался с загрузкой и температурой GPU не только NVIDIA, но и AMD : применил функции из atiadlxx.dll . Попутно мониторятся частоты потокового процессора ( GPU) и его памяти, MHz, а также скорость вращения вентилятора видеокарты (в %). Это всё для NVIDIA- AMD. Перезалил весь пример в ту же новую папку для скачивания OpenCL_Demo2017 Barrier and Local_Memory REDUCT (см. ссылку http://gofile.me/2Zesj/C0f3wb1o ). Там же в под-папке с Supporting Information в названии есть примеры на C++ применения библиотек nvml.dll ( NVIDIA) и atiadlxx.dll ( AMD) и кое-какая документация по этим библиотекам (для AMD - в формате Word и html). Непосредственно файлы на C++ из папки Supporting Information в проекте НЕ используются. Кроме того, документация atiadlxx.dll есть в папке Supporting Information в html-формате : в ней надо открыть в любом броузере ADL_SDK.html. Это что касается AMD. Ссылку на мануал для библиотеки NVIDIA - nvml.dll - уже приводил выше: https://docs.nvidia.com/deploy/pdf/NVML_API...rence_Guide.pdfКод основного модуля ProcessorUsage.pas (для определения загрузки CPU- GPU- NVIDIA- AMD), компиляция Delphi XE8 под Win64 !! - дублирую ниже ( версия от 24.01.18) Код | unit ProcessorUsage; {=====================================================================} {**** Моделирование 3D течений, переноса тепла и деформаций дна. ****} {==== Модуль определения загрузки CPU (общей и процессом) и GPU ====} {========= Прокофьев В.А. АО "ВНИИГ им. Б.Е.Веденеева" ========} {========= 01.2018 С.Петербург. e-mail: [email protected] ========} {=====================================================================} interface
uses Windows, SysUtils, Dialogs;
// В начале 1 раз вызвать с параметром Initialize = True procedure CPUusage(const Initialize : Boolean; out Total, MyProcess, TotalMemory, ProcessMemory : Integer); //... Температуры выдаются в град.С, частоты- в MHz, ... //... потребляемая мощность- в Ваттах, остальное- в % ... procedure GPUusageInitialize; // Запустить 1 раз в начале procedure GPUusageNVIDIA(const GPU_num : Byte; out GPU_usage, MemoryController, Memory, Temperature, GPU_freq, MEM_freq, FanSpeed, Power : Integer); procedure GPUusageAMD(const GPU_num : Byte; out GPU_usage, Temperature, GPU_freq, Mem_freq, FanSpeed : Integer); procedure GPUusageShutdown; // Запустить 1 раз в конце // type TypeGPU = (gpuNO = 0, gpuNVIDIA = 1, gpuAMD = 2); // var Initialize_NVIDIA_OK : Boolean = False; Initialize_AMD_OK : Boolean = False; // //===================================================================== implementation //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //++++++++++++++++ Сначала работаем с загрузкой CPU +++++++++++++++++++ //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ var OldIdleTime64, OldSysTime64, OldProcT64 : Int64; // {==== Определение размера выделенной приложению памяти (в Байтах) ====} function MyGetAllocatedMemory: UInt64; var St: TMemoryManagerState; Sb: TSmallBlockTypeState; begin GetMemoryManagerState(St); Result := St.TotalAllocatedMediumBlockSize + St.TotalAllocatedLargeBlockSize; For Sb in St.SmallBlockTypeStates do Result := Result + Sb.UseableBlockSize * Sb.AllocatedBlockCount; end;
//===================================================================== //========== Определение загрузки CPU (в процентах 0..100) ============ //===================================================================== procedure CPUusage(const Initialize : Boolean; out Total, MyProcess, TotalMemory, ProcessMemory : Integer); var IdleTime, CreationTime, ExitTime, KernelTime, UserTime : TFileTime; IdleTime64, KernelTime64, UserTime64, NewProcT64, DIdle, Dsum : Int64; MemStatusCPU: TMemoryStatus; begin Try Dsum := 1; //... только чтобы не было Warning //=== 1) Определим загрузку CPU всеми процессами в системе (Total) ==== GetSystemTimes(IdleTime, KernelTime, UserTime); // См. https://www.codeproject.com/Articles/9113/ // Get-CPU-Usage-with-GetSystemTimes Move(IdleTime, IdleTime64, 8); Move(KernelTime, KernelTime64, 8); Move(UserTime, UserTime64, 8); If Initialize then Total := 0 else begin DIdle := IdleTime64 - OldIdleTime64; Dsum := KernelTime64 + UserTime64 - OldSysTime64; If Dsum <= 0 then DSum := 1; // KernelTime включает в себя и IdleTime ! Total := Round(100.0 * (Dsum - Didle) / Dsum); If Total < 0 then Total := 0; If Total > 100 then Total := 100; end; OldIdleTime64 := IdleTime64; // Время простоя CPU // Общее время, включая простой OldSysTime64 := KernelTime64 + UserTime64; // //=== 2) Определим загрузку CPU только нашим процессом (MyProcess) ==== GetProcessTimes(GetCurrentProcess, CreationTime, ExitTime, KernelTime, UserTime); Move(KernelTime, KernelTime64, 8); Move(UserTime, UserTime64, 8); NewProcT64 := KernelTime64 + UserTime64; // Dsum- интервал астрономического времени между 2-мя вызовами CPUusage If Initialize then MyProcess := 0 else MyProcess := Round(100.0 * (NewProcT64 - OldProcT64) / Dsum); If MyProcess < 0 then MyProcess := 0; If MyProcess > 100 then MyProcess := 100; OldProcT64 := NewProcT64; // //=============== 3) Определим загрузку памяти CPU ==================== MemStatusCPU.dwLength := SizeOf(MemStatusCPU); GlobalMemoryStatus(MemStatusCPU); TotalMemory := MemStatusCPU.dwMemoryLoad; // Всего занято процентов ProcessMemory := Round(100 * MyGetAllocatedMemory / MemStatusCPU.dwTotalPhys); // Только нашим процессом, в процентах except Total := 0; MyProcess := 0; TotalMemory := 0; ProcessMemory := 0; end; end;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //+++++++++++ Далее работаем с имеющимися в системе GPU +++++++++++++++ //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ type Empty_Record = record end; // По аналогии с OpenCL Headers nvmlDevice_t = ^Empty_Record; // в Header-файле для MS C++ также p_nvmlDevice_t = ^nvmlDevice_t; nvmlReturn_t = Integer; //..... Для определения загрузки GPU и контроллера памяти NVIDIA ...... nvmlUtilization_t = packed record GPU, Mem : UInt; end; p_nvmlUtilization_t = ^nvmlUtilization_t; //......... Для определения процентной загрузки памяти NVIDIA ......... nvmlMemory_t = packed record Total, Free, Used : UInt64; end; p_nvmlMemory_t = ^nvmlMemory_t; // //~~~~ Clock types (для определения частот GPU и Memory у NVIDIA) ~~~~~ const NVML_CLOCK_GRAPHICS = 0; // Graphics clock domain NVML_CLOCK_MEM = 2; // Memory clock domain
var // Описываем прототипы вызываемых из nvml.dll функций nvmlInit : function() : nvmlReturn_t; stdcall; nvmlShutdown : function() : nvmlReturn_t; stdcall; //..................................................................... nvmlDeviceGetCount : function(pDevCount: pUInt) : nvmlReturn_t; stdcall; //..................................................................... nvmlDeviceGetHandleByIndex : function (GPUnum : UInt; pHandle: p_nvmlDevice_t) : nvmlReturn_t; stdcall; //..................................................................... nvmlDeviceGetUtilizationRates : function (GPU_Handle1 : nvmlDevice_t; pUtilization: p_nvmlUtilization_t) : nvmlReturn_t; stdcall; //..................................................................... nvmlDeviceGetMemoryInfo : function(GPU_Handle1 : nvmlDevice_t; pDeviceMem: p_nvmlMemory_t) : nvmlReturn_t; stdcall; //..................................................................... nvmlDeviceGetTemperature : function(GPU_Handle1 : nvmlDevice_t; SensorType : Integer; pTemp : pUInt) : nvmlReturn_t; stdcall; //..................................................................... nvmlDeviceGetClockInfo : function(GPU_Handle1 : nvmlDevice_t; ClockType: Integer; Clock : pUInt) : nvmlReturn_t; stdcall; //..................................................................... nvmlDeviceGetFanSpeed : function(GPU_Handle1 : nvmlDevice_t; speed: pUInt) : nvmlReturn_t; stdcall; //..................................................................... nvmlDeviceGetPowerUsage : function(GPU_Handle1 : nvmlDevice_t; pPower : pUint) : nvmlReturn_t; stdcall; // // //+++++++++++ Типы для библиотечных функций atiadlxx.dll ++++++++++++++ // (AMD - GPU) // MyMALLOC подсмотрел здесь : http://www.delphipraxis.net/ // 131660-uebersetzung-c-pascal-callback-zugriffsverletzung.html type tADL_MAIN_MALLOC_CALLBACK = function(iSize : Integer) : Pointer; stdcall; pADL_MAIN_MALLOC_CALLBACK = ^tADL_MAIN_MALLOC_CALLBACK; // Указатель на эту ф-ю выделения памяти передаётся в инициализацию AMD function MyMALLOC(iSize : Integer) : Pointer; stdcall; begin Result := AllocMem(iSize); end;
//...... Для получении информации о загрузке GPU-AMD и частотах ....... type ADLPMActivity = packed record iSize : Integer; // Must be set to the size of the structure iEngineClock : Integer; // Current engine frequency [in 10KHz] iMemoryClock : Integer; // Current memory frequency [in 10KHz] iVddc : Integer; // Current core voltage. iActivityPercent : Integer; // GPU utilization. iCurrentPerformanceLevel : Integer; //Performance level index. iCurrentBusSpeed : Integer; // Current PCIE bus speed. iCurrentBusLanes : Integer; // Number of PCIE bus lanes. iMaximumBusLanes : Integer; // Maximum number of PCIE bus lanes. iReserved : Integer; // Reserved for future purposes. end; pADLPMActivity = ^ADLPMActivity;
//........ Для получении информации о температуре GPU-AMD ............. type ADLTemperature = packed record iSize : Integer; // Must be set to the size of the structure iTemperature : Integer; // Temperature in millidegrees Celsius end; pADLTemperature = ^ADLTemperature;
//.......... Для получении информации о памяти на борту AMD ........... type ADLMemoryInfo = packed record iMemorySize : Int64; // Memory size in bytes // Только AnsiChar позволяет прочитать тип памяти из следующей строки strMemoryType: array[0..255] of AnsiChar; iMemoryBandwidth : Int64; // Memory bandwidth in Mbytes/s. end; pADLMemoryInfo = ^ADLMemoryInfo;
//........ Для получении информации о скорости вентилятора AMD ........ const ADL_DL_FANCTRL_SPEED_TYPE_PERCENT = 1; ADL_DL_FANCTRL_FLAG_USER_DEFINED_SPEED = 1;
type ADLFanSpeedValue = packed record iSize : Integer; // Must be set to the size of the structure // Possible values: ADL_DL_FANCTRL_SPEED_TYPE_PERCENT or // ADL_DL_FANCTRL_SPEED_TYPE_RPM iSpeedType : Integer; iFanSpeed : Integer; // Fan speed value // The only flag for now is: ADL_DL_FANCTRL_FLAG_USER_DEFINED_SPEED iFlags : Integer; end; pADLFanSpeedValue = ^ADLFanSpeedValue; // //=== Функции Overdrive6 работают не на всех системах => Overdrive5 === var // Описываем прототипы вызываемых из atiadlxx.dll функций ADL_Main_Control_Create : function( callback : pADL_MAIN_MALLOC_CALLBACK; iEnumConnectedAdapters : Integer) : nvmlReturn_t; stdcall; //..................................................................... ADL_Main_Control_Destroy: function() : nvmlReturn_t; stdcall; //..................................................................... ADL_Overdrive5_CurrentActivity_Get: function(iAdapterIndex : Integer; pActivity : pADLPMActivity) : nvmlReturn_t; stdcall; //..................................................................... ADL_Adapter_NumberOfAdapters_Get : function(pNumAdapters : pInt) : nvmlReturn_t; stdcall; //..................................................................... ADL_Adapter_Active_Get : function(iAdapterIndex : Integer; pStatus : pInt) : nvmlReturn_t; stdcall; //..................................................................... ADL_Overdrive5_Temperature_Get : function(iAdapterIndex : Integer; iThermalControllerIndex : Integer; pTemperature : pADLTemperature) : nvmlReturn_t; stdcall; //..................................................................... ADL_Overdrive5_FanSpeed_Get : function(iAdapterIndex : Integer; iThermalControllerIndex : Integer; pFanSpeedValue : pADLFanSpeedValue) : nvmlReturn_t; stdcall; //..................................................................... ADL_Adapter_MemoryInfo_Get : function(iAdapterIndex : Integer; pMemoryInfo: pADLMemoryInfo) : nvmlReturn_t; stdcall; //.....................................................................
var GPU_count_NVIDIA, GPU_count_AMD: Integer; //UInt; LibHandleNV, LibHandleAMD: hModule; ShowMessageAMD : Boolean; // //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //++++ Инициализация функций из библиотек nvml.dll и atiadlxx.dll +++++ //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ procedure GPUusageInitializeNVIDIA; forward; procedure GPUusageInitializeAMD; forward; // procedure GPUusageInitialize; begin GPUusageInitializeNVIDIA; GPUusageInitializeAMD; end; // //===================================================================== //==== Сначала пытаемся инициализировать библиотеку для NVIDIA ====== //===================================================================== procedure GPUusageInitializeNVIDIA; //.... По умолчанию устанавливается только версия библиотеки 64bit .... // См. https://devtalk.nvidia.com/default/topic/525514/ // can-39-t-find-nvml-dll-in-display-drivers/ const nvml_Lib : WideString = 'C:\Program Files\NVIDIA Corporation\NVSMI\nvml.dll'; //..................................................................... procedure ProcNV(var Fun: Pointer; const FunName: WideString); begin FreeAndNil(Fun); // Здесь 2-ой параметр м.б. либо ANSI, либо Unicode=WideChar - overload Fun := GetProcAddress(LibHandleNV, PWideChar(FunName)); end; //..................................................................... begin If not Initialize_NVIDIA_OK then try // Проверим, существует ли по указанному пути файл библиотеки nvml.dll If not FileExists(nvml_Lib) then raise EAbort.Create(''); // Лучше конкретно писать LoadLibraryW : работаем с Unicode = PWideChar LibHandleNV := LoadLibraryW(PWideChar(nvml_Lib)); // Если не удалось загрузить библиотеку nvml.dll If LibHandleNV = 0 then raise EAbort.Create(''); // Определяем адреса всех необходимых процедур из библиотеки NVIDIA ProcNV(@nvmlInit, 'nvmlInit'); ProcNV(@nvmlShutdown, 'nvmlShutdown'); ProcNV(@nvmlDeviceGetCount, 'nvmlDeviceGetCount'); ProcNV(@nvmlDeviceGetHandleByIndex, 'nvmlDeviceGetHandleByIndex'); ProcNV(@nvmlDeviceGetUtilizationRates, 'nvmlDeviceGetUtilizationRates'); ProcNV(@nvmlDeviceGetMemoryInfo, 'nvmlDeviceGetMemoryInfo'); ProcNV(@nvmlDeviceGetTemperature, 'nvmlDeviceGetTemperature'); ProcNV(@nvmlDeviceGetClockInfo, 'nvmlDeviceGetClockInfo'); ProcNV(@nvmlDeviceGetFanSpeed, 'nvmlDeviceGetFanSpeed'); ProcNV(@nvmlDeviceGetPowerUsage, 'nvmlDeviceGetPowerUsage'); // Инициализация функций библиотеки nvml.dll If nvmlInit() <> 0 then raise EAbort.Create(''); // Определение кол-ва GPU в конкретной системе : только для контроля If nvmlDeviceGetCount(@GPU_count_NVIDIA) <> 0 then raise EAbort.Create(''); Initialize_NVIDIA_OK := True; except Initialize_NVIDIA_OK := False; FreeLibrary(LibHandleNV); end; end; // //===================================================================== //====== Далее пытаемся инициализировать библиотеку для AMD ========= //===================================================================== procedure GPUusageInitializeAMD; var MaxAMD, iAdapterAMD, StatusAMD : Integer; //..................................................................... procedure ProcAMD(var Fun: Pointer; const FunName: WideString); begin FreeAndNil(Fun); // Здесь 2-ой параметр м.б. либо ANSI, либо Unicode(WideChar)- overload Fun := GetProcAddress(LibHandleAMD, PWideChar(FunName)); end; //..................................................................... begin ShowMessageAMD := True; If not Initialize_AMD_OK then try LibHandleAMD := LoadLibraryW(PWideChar(WideString('atiadlxx.dll'))); // Если не удалось загрузить библиотеку atiadlxx.dll If LibHandleAMD = 0 then raise EAbort.Create(''); // Определяем адреса всех необходимых процедур из библиотеки AMD ProcAMD(@ADL_Main_Control_Create, 'ADL_Main_Control_Create'); ProcAMD(@ADL_Main_Control_Destroy, 'ADL_Main_Control_Destroy'); ProcAMD(@ADL_Overdrive5_CurrentActivity_Get, 'ADL_Overdrive5_CurrentActivity_Get'); ProcAMD(@ADL_Adapter_NumberOfAdapters_Get, 'ADL_Adapter_NumberOfAdapters_Get'); ProcAMD(@ADL_Adapter_Active_Get, 'ADL_Adapter_Active_Get'); ProcAMD(@ADL_Overdrive5_Temperature_Get, 'ADL_Overdrive5_Temperature_Get'); ProcAMD(@ADL_Overdrive5_FanSpeed_Get, 'ADL_Overdrive5_FanSpeed_Get'); ProcAMD(@ADL_Adapter_MemoryInfo_Get, 'ADL_Adapter_MemoryInfo_Get'); // //....... Определяем GPU_HandleAMD (инициализация функций AMD) ........ // 2-ой парметр = 0 : значит, что для всех доступных AMD-устройств If ADL_Main_Control_Create(@MyMALLOC, 0) <> 0 then raise EAbort.Create(''); // //=====> Получаем информацию об общем количестве адаптеров AMD <======= If ADL_Adapter_NumberOfAdapters_Get(@MaxAMD) <> 0 then raise EAbort.Create(''); //......... Подсчитаем количество активных адаптеров AMD .............. GPU_count_AMD := 0; // На моноблоке ASUS ET2702i вышло MaxAMD = 6 ! For iAdapterAMD := 0 to MaxAMD - 1 do begin If ADL_Adapter_Active_Get(iAdapterAMD, @StatusAMD) <> 0 then raise EAbort.Create(''); If StatusAMD <> 0 then Inc(GPU_count_AMD); end; //..................................................................... Initialize_AMD_OK := True; except Initialize_AMD_OK := False; FreeLibrary(LibHandleAMD); end; end; // procedure NVIDIA_Shutdown; forward; //===================================================================== //===== Определение загрузки NVIDIA-GPU с номером GPU_num (от 0) ====== //===================================================================== procedure GPUusageNVIDIA(const GPU_num : Byte; out GPU_usage, MemoryController, Memory, // Всё в процентах Temperature, // degrees C GPU_freq, MEM_freq, // MHz FanSpeed, // Скорость вентилятора в процентах Power : Integer); // Потребляемая мощность в Ваттах var GPU_Handle : nvmlDevice_t; UtilGPU : nvmlUtilization_t; MemGPU : nvmlMemory_t; nvmlValue : UInt; begin //!!! Значение -1 -это признак, что параметр не удалось определить !!!! GPU_usage := -1; MemoryController := -1; Memory := -1; GPU_freq := -1; MEM_freq := -1; Temperature := -1; FanSpeed := -1; Power := -1; If Initialize_NVIDIA_OK and (GPU_num < GPU_count_NVIDIA) then try // //=============> Определение Handle для выбранного GPU <=============== If nvmlDeviceGetHandleByIndex(GPU_num, @GPU_Handle) <> 0 then raise EAbort.Create(''); // След. вызовы будут с ошибками, если nvml.dll от другой видеокарты!! // //====> Получаем информацию о загрузке потоковых процессоров GPU <===== If nvmlDeviceGetUtilizationRates(GPU_Handle, @UtilGPU) = 0 then begin GPU_usage := UtilGPU.GPU; MemoryController := UtilGPU.Mem; end; // //=======> Получаем информацию об использовании памяти GPU <=========== If nvmlDeviceGetMemoryInfo(GPU_Handle, @MemGPU) = 0 then Memory := Round( 100 * MemGPU.Used / MemGPU.Total ); // //=========> Получаем информацию о температуре NVIDIA-GPU <============ If nvmlDeviceGetTemperature(GPU_Handle, 0, @nvmlValue) = 0 then Temperature := nvmlValue; // //=====> Получаем информацию о частотах процессора и памяти GPU <====== If nvmlDeviceGetClockInfo(GPU_Handle, NVML_CLOCK_GRAPHICS, @nvmlValue) = 0 then GPU_freq := nvmlValue; If nvmlDeviceGetClockInfo(GPU_Handle, NVML_CLOCK_MEM, @nvmlValue) = 0 then MEM_freq := nvmlValue; // //=====> Получаем информацию о скорости вентилятора NVIDIA-GPU <======= If nvmlDeviceGetFanSpeed(GPU_Handle, @nvmlValue) = 0 then FanSpeed := nvmlValue; //...в процентах, а не в RPM // //=====> Получаем информацию о потребляемой мощности NVIDIA-GPU <====== If nvmlDeviceGetPowerUsage(GPU_Handle, @nvmlValue) = 0 then Power := Round(1E-3 * nvmlValue); //...миллиВатты в Ватты // except NVIDIA_Shutdown; end; // Если не удалось определить ни одного параметра, отключаем библиотеку If GPU_usage + MemoryController + Memory + GPU_freq + MEM_freq + Temperature + FanSpeed + Power = -8 then NVIDIA_Shutdown; end; // procedure AMD_Shutdown; forward; //===================================================================== //======= Определение загрузки AMD-GPU с номером GPU_num (от 0) ======= //===================================================================== procedure GPUusageAMD(const GPU_num : Byte; out GPU_usage, Temperature, GPU_freq, Mem_freq, FanSpeed : Integer); var MemoryInfo : ADLMemoryInfo; MemoryType : String; MyFanSpeed : ADLFanSpeedValue; MyActivity : ADLPMActivity; MyTemp : ADLTemperature; const CRLF = #13#10; // Переход на новую строку для ShowMessage begin //!!! Значение -1 -это признак, что параметр не удалось определить !!!! GPU_usage := -1; GPU_freq := -1; MEM_freq := -1; Temperature := -1; FanSpeed := -1; If Initialize_AMD_OK and (GPU_num < GPU_count_AMD) then try // //====> Получаем информацию о загрузке потоковых процессоров GPU <===== MyActivity.iSize := SizeOf(ADLPMActivity); If ADL_Overdrive5_CurrentActivity_Get(GPU_num, @MyActivity) = 0 then begin GPU_usage := MyActivity.iActivityPercent; GPU_freq := Round(0.01 * MyActivity.iEngineClock); MEM_freq := Round(0.01 * MyActivity.iMemoryClock); end; // //===========> Получаем информацию о температуре AMD-GPU <============= MyTemp.iSize := SizeOf(ADLTemperature); If ADL_Overdrive5_Temperature_Get(GPU_num, 0, @MyTemp) = 0 then // Температура была в милли-градусах C Temperature := Round(0.001 * MyTemp.iTemperature); // //======> Получаем информацию о скорости вентилятора AMD-GPU <========= MyFanSpeed.iSize := SizeOf(ADLFanSpeedValue); MyFanSpeed.iFlags := ADL_DL_FANCTRL_FLAG_USER_DEFINED_SPEED; MyFanSpeed.iSpeedType := ADL_DL_FANCTRL_SPEED_TYPE_PERCENT; If ADL_Overdrive5_FanSpeed_Get(GPU_num, 0, @MyFanSpeed) = 0 then FanSpeed := MyFanSpeed.iFanSpeed; // //...... Один раз покажем информацию о памяти на борту AMD-GPU ........ If ShowMessageAMD then begin ShowMessageAMD := False; //===> Получаем информацию об общем количестве памяти на борту GPU <=== If ADL_Adapter_MemoryInfo_Get(GPU_num, @MemoryInfo) = 0 then begin // Переводим AnsiString --> String , контролируем длину строки MemoryType := String(MemoryInfo.strMemoryType); ShowMessage('Active GPU_count_AMD = ' + IntToStr(GPU_count_AMD) + CRLF + 'Memory (' + MemoryType + ') = ' + IntToStr(Round(MemoryInfo.iMemorySize / (1024*1024))) + ' MBytes' + CRLF + 'MemoryType string Length = ' + IntToStr(Length(MemoryType)) + CRLF + 'Memory Bandwidth= ' + IntToStr(MemoryInfo.iMemoryBandwidth) + ' MBytes/s'); end; end; except AMD_Shutdown; end; // Если не удалось определить ни одного параметра, отключаем библиотеку If GPU_usage + GPU_freq + MEM_freq + Temperature + FanSpeed = -5 then AMD_Shutdown; end; // //--------------------------------------------------------------------- //----------- Отключение библиотек nvml.dll и atiadlxx.dll ------------ //--------------------------------------------------------------------- procedure NVIDIA_Shutdown; begin If Initialize_NVIDIA_OK then try Initialize_NVIDIA_OK := False; nvmlShutdown(); finally FreeLibrary(LibHandleNV); end; end; //..................................................................... procedure AMD_Shutdown; begin If Initialize_AMD_OK then try Initialize_AMD_OK := False; ADL_Main_Control_Destroy(); finally FreeLibrary(LibHandleAMD); end; end; //..................................................................... procedure GPUusageShutdown; begin NVIDIA_Shutdown; AMD_Shutdown; end;
end.
|
Так и не смог пока понять, как определить кол-во свободной памяти на карте AMD : для NVIDIA это удалось, а для AMD можно только общее кол-во памяти на борту определить (выдаётся в виде экранного сообщения в коде выше). Между тем, готовые утилиты типа GPU-z 2.5.0 дают кол-во занятой/свободной памяти на картах AMD, значит, какой-то способ есть . И всё это надо под Win64! С потребляемой мощностью именно для AMD - тоже затык... На зарубежных форумах этот вопрос поднимался, причём совсем недавно, но ответа не нашёл: https://community.amd.com/thread/223995Это сообщение отредактировал(а) Prok12 - 29.1.2018, 10:42
|