Определение загрузки и температуры
GPU типа
AMD добавил в пример (ранее всё было только для
NVIDIA). Использовал библиотеку
atiadlxx.dll. Эта библиотека устанавливается автоматически при установке драйверов видео-карты
AMD (у меня это простенькая
Radeon M275x). Пример перезалил в ту же папку для скачивания
http://gofile.me/2Zesj/C0f3wb1o , в ту же уже ранее добавленную под-папку:
OpenCL_Demo2017 Barrier and Local_Memory REDUCT
Но вот как определить, сколько памяти на
GPU именно
AMD уже занято - не разобрался. В стандартных утилитах типа
GPU-z 2.5.0 это как-то делается и для
AMD тоже : значит, способ есть
. Может кто-то подсказать?
Ниже дублирую
Delphi XE8 код для определения загрузки
CPU -
GPU-
NVIDIA-
AMD (
компиляция под Win64 !)
Код:
unit ProcessorUsage;
{=====================================================================}
{**** Моделирование 3D течений, переноса тепла и деформаций дна. ****}
{==== Модуль определения загрузки CPU (общей и процессом) и GPU ====}
{========= Прокофьев В.А. АО "ВНИИГ им. Б.Е.Веденеева" ========}
{========= 01.2018 С.Петербург. e-mail: Prok12@Rambler.ru ========}
{=====================================================================}
interface
uses Windows, SysUtils, Dialogs;
// В начале 1 раз вызвать с параметром Initialize = True
procedure CPUusage(const Initialize : Boolean;
out Total, MyProcess : Integer);
//... Температуры выдаются в град.С, частоты- в MHz, остальное- в % ...
procedure GPUusageInitialize; // Запустить 1 раз в начале
procedure GPUusageNVIDIA(const GPU_num : Byte;
out GPU_usage, MemoryController, Memory,
Temperature, GPU_freq, MEM_freq, FanSpeed : 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;
//
//========== Определение загрузки CPU (в процентах 0..100) ============
procedure CPUusage(const Initialize : Boolean;
out Total, MyProcess : Integer);
var IdleTime, CreationTime, ExitTime, KernelTime, UserTime : TFileTime;
IdleTime64, KernelTime64, UserTime64, NewProcT64, DIdle, Dsum : Int64;
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;
except
Total := 0; MyProcess := 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;
//
//
//+++++++++++ Типы для библиотечных функций 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;
//