Форум по программированию Delphi Sources

 



Вернуться   Форум по программированию Delphi Sources > Все о Delphi > Программа и интерфейс
Ник
Пароль
Регистрация <<         Правила форума         >> FAQ Пользователи Календарь Поиск Сообщения за сегодня Все разделы прочитаны

Ответ
 
Опции темы Поиск в этой теме Опции просмотра
  #1  
Старый 28.12.2017, 16:43
Prok186 Prok186 вне форума
Прохожий
 
Регистрация: 19.06.2011
Сообщения: 21
Репутация: 10
Счастье Снова Delphi & OpenCL + программное определение загрузки GPU & CPU (готовый пример)

Уже более года назад приводил здесь на форуме пример работы с OpenCL в связке с Delphi - http://www.delphisources.ru/forum/sh...ad.php?t=28188
-------------------------------------------------------------------
Дополню его. Открываю отдельную тему, т.к. новый пример м.б. интересен и безотносительно к OpenCL , поскольку в нём есть программное (прямо из Delphi-кода) определение:
  • общей загрузки CPU ;
  • загрузки CPU данной задачей ;
  • загрузки GPU (общей);
  • загрузки контроллера памяти GPU ;
  • процента использованной памяти GPU ;
  • температуры GPU .

Внутри той же ссылки для скачивания http://gofile.me/2Zesj/C0f3wb1o добавил папку:

OpenCL_Demo2017 Barrier and Local_Memory REDUCT

В ней новый пример под Delphi XE8 64bit (работает и при компиляции в Delphi под Win32, но с ограничениями, о которых будет сказано ниже).

Отличия:
1. Добавлен пример простейшей редукции с использованием barrier и LocalMemory с обилием комментариев внутри Kernel-файла ProgramGPU1.cpp

2. Показано, как внутри Kernel создать а-ля динамический массив (стандарт языка OpenCL 1.2 этого не позволяет).

3. Главное. На форме (см. скан экрана Reduct DEMO.tiff в указанной выше новой папке) добавлены Gauge-компоненты, показывающие перечисленные выше параметры загрузки системы (CPU-GPU).

4. Для определения загрузки GPU используется nvml.dll
( мануал 2017 здесь: https://docs.nvidia.com/deploy/pdf/N...ence_Guide.pdf ),
так что последние 4 параметра определяются только для карт NVIDIA, и при компиляции в Delphi под 64bit. Эта динамич. библиотека для каждой карты NVIDIA - своя,
обычно при установке драйвера карты она попадает в папку
C:\Program Files\NVIDIA Corporation\NVSMI\nvml.dll (этот путь прямо прописан в прилагаемом примере по ссылке).

Всё что связано с определением загрузки CPU-GPU находится в отдельном модуле ProcessorUsage.pas, который может быть применён и для других программ (без OpenCL).

5. Если есть желание попробовать OpenCL не только на видеокартах, но и на процессорах INTEL, надо поставить драйвер https://software.intel.com/en-us/art...st_CPU_runtime

6. Ещё раз напоминаю, что при запуске *.exe рядом с ним должны лежать два текстовых файла *.cpp - они будут отправлены на компиляцию драйверу видеокарты!

7. Пример делался в Delphi XE8, компилировался под 64bit. Система - Windows 10Pro. При компиляции под 32bit не будут отображаться компоненты загрузки GPU (даже если у вас карта NVIDIA, и по указанному пути удастся найти библиотеку nvml.dll). Кроме того, из-за ограничений в адресации памяти под 32bit, максимальный размер матриц 1400 x 8 (так и задано по умолчанию на форме).
---------
Буду весьма признателен , если кто-то подскажет способ измерения загрузки GPU от AMD, и самое простое - его температуры. Есть похожая DLL - как у NVIDIA, только для AMD Radeon? Может, эти: atiadlxx.dll , atiadlxy.dll , GPUPerfAPIGL.dll ?

Последний раз редактировалось Prok186, 29.12.2017 в 13:54.
Ответить с цитированием
  #2  
Старый 03.01.2018, 17:20
Prok186 Prok186 вне форума
Прохожий
 
Регистрация: 19.06.2011
Сообщения: 21
Репутация: 10
Подмигивание GPU usage NVIDIA & AMD

Определение загрузки и температуры 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;
//

Последний раз редактировалось Prok186, 05.01.2018 в 15:20.
Ответить с цитированием
  #3  
Старый 03.01.2018, 17:21
Prok186 Prok186 вне форума
Прохожий
 
Регистрация: 19.06.2011
Сообщения: 21
Репутация: 10
По умолчанию продолжение кода

Код:
//...... Для получении информации о загрузке GPU-AMD и частотах .......
type ADLOD6CurrentStatus = packed record
    iEngineClock : Integer;      // Current engine frequency [in 10KHz]
    iMemoryClock : Integer;      // Current memory frequency [in 10KHz]
// Current GPU activity in percent, this indicates how busy the GPU is
    iActivityPercent : Integer;
    iCurrentPerformanceLevel : Integer;   // Reserved for future use
    iCurrentBusSpeed : Integer;  // Current PCI-E bus speed
    iCurrentBusLanes : Integer;  // Current PCI-E bus # of lanes
    iMaximumBusLanes : Integer;  // Max possible PCI-E bus # of lanes
    iExtValue : Integer;         // Value for future extension
    iExtMask : Integer;          // Mask for future extension
   end;
  pADLOD6CurrentStatus =  ^ADLOD6CurrentStatus;

//.......... Для получении информации о памяти на борту 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;
//
//=====================================================================
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_Overdrive6_CurrentStatus_Get : function(iAdapterIndex : Integer;
    pCurrentStatus : pADLOD6CurrentStatus) :  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_Overdrive6_Temperature_Get : function(iAdapterIndex : Integer;
    pTemp : pInt) :  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: THandle;
    ShowMesAMD : Boolean;
//
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//++++ Инициализация функций из библиотек nvml.dll и atiadlxx.dll +++++
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
procedure GPUusageInitialize;
var MaxAMD, iAdapterAMD, StatusAMD : Integer;
//.... По умолчанию устанавливается только версия библиотеки 64bit ....
// См.  https://devtalk.nvidia.com/default/topic/525514/
//   can-39-t-find-nvml-dll-in-display-drivers/
const nvml_Lib = 'C:\Program Files\NVIDIA Corporation\NVSMI\nvml.dll';
begin
//
ShowMesAMD := True;
//====  Сначала пытаемся инициализировать библиотеку для NVIDIA  ======
   Try
// Проверим, существует ли по указанному пути файл библиотеки nvml.dll
   If not FileExists(nvml_Lib) then raise EAbort.Create('');
   LibHandleNV := LoadLibrary(nvml_Lib);
// Если не удалось загрузить библиотеку nvml.dll
   If LibHandleNV = 0 then raise EAbort.Create('');
// Определяем адреса всех необходимых процедур из библиотеки NVIDIA
   @nvmlInit := GetProcAddress(LibHandleNV, 'nvmlInit');
   @nvmlShutdown := GetProcAddress(LibHandleNV, 'nvmlShutdown');
   @nvmlDeviceGetCount :=
     GetProcAddress(LibHandleNV, 'nvmlDeviceGetCount');
   @nvmlDeviceGetHandleByIndex :=
     GetProcAddress(LibHandleNV, 'nvmlDeviceGetHandleByIndex');
   @nvmlDeviceGetUtilizationRates :=
     GetProcAddress(LibHandleNV, 'nvmlDeviceGetUtilizationRates');
   @nvmlDeviceGetMemoryInfo :=
     GetProcAddress(LibHandleNV, 'nvmlDeviceGetMemoryInfo');
   @nvmlDeviceGetTemperature :=
     GetProcAddress(LibHandleNV, 'nvmlDeviceGetTemperature');
   @nvmlDeviceGetClockInfo :=
     GetProcAddress(LibHandleNV, 'nvmlDeviceGetClockInfo');
   @nvmlDeviceGetFanSpeed :=
     GetProcAddress(LibHandleNV, 'nvmlDeviceGetFanSpeed');
// Инициализация функций библиотеки 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;
//
//======  Далее пытаемся инициализировать библиотеку для AMD  =========
   Try
   LibHandleAMD := LoadLibrary('atiadlxx.dll');
// Если не удалось загрузить библиотеку atiadlxx.dll
   If LibHandleAMD = 0 then raise EAbort.Create('');
// Определяем адреса всех необходимых процедур из библиотеки AMD
   @ADL_Main_Control_Create :=
    GetProcAddress(LibHandleAMD, 'ADL_Main_Control_Create');
   @ADL_Main_Control_Destroy :=
    GetProcAddress(LibHandleAMD, 'ADL_Main_Control_Destroy');
   @ADL_Overdrive6_CurrentStatus_Get :=
    GetProcAddress(LibHandleAMD, 'ADL_Overdrive6_CurrentStatus_Get');
   @ADL_Adapter_NumberOfAdapters_Get :=
    GetProcAddress(LibHandleAMD, 'ADL_Adapter_NumberOfAdapters_Get');
   @ADL_Adapter_Active_Get :=
    GetProcAddress(LibHandleAMD, 'ADL_Adapter_Active_Get');
   @ADL_Overdrive6_Temperature_Get :=
    GetProcAddress(LibHandleAMD, 'ADL_Overdrive6_Temperature_Get');
   @ADL_Overdrive5_FanSpeed_Get :=
    GetProcAddress(LibHandleAMD, 'ADL_Overdrive5_FanSpeed_Get');
   @ADL_Adapter_MemoryInfo_Get :=
    GetProcAddress(LibHandleAMD, '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;
//

Последний раз редактировалось Prok186, 05.01.2018 в 15:17.
Ответить с цитированием
  #4  
Старый 05.01.2018, 15:18
Prok186 Prok186 вне форума
Прохожий
 
Регистрация: 19.06.2011
Сообщения: 21
Репутация: 10
По умолчанию последний 3-й фрагмент кода

Код:
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 : 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;
   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 );
//
//=============> Получаем информацию о температуре 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;
//
//========> Получаем информацию о скорости вентилятора GPU <===========
   If nvmlDeviceGetFanSpeed(GPU_Handle, @nvmlValue) = 0
    then FanSpeed := nvmlValue;    //...в процентах, а не в RPM
   except
   NVIDIA_Shutdown;
   end;
// Если не удалось определить ни одного параметра, отключаем библиотеку
If GPU_usage + MemoryController + Memory + GPU_freq + MEM_freq +
 Temperature + FanSpeed = -7 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 Temp : Integer;
    AMD_Status : ADLOD6CurrentStatus;
    MemoryInfo : ADLMemoryInfo;      MemoryType : String;
    FanSpeedValue : ADLFanSpeedValue;
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 <=====
      If ADL_Overdrive6_CurrentStatus_Get(GPU_num, @AMD_Status) = 0
      then begin
      GPU_usage := AMD_Status.iActivityPercent;
// Частоты для AMD в десятках KHz - сразу переведём в MHz
      GPU_freq := Round(0.01 * AMD_Status.iEngineClock);
      MEM_freq := Round(0.01 * AMD_Status.iMemoryClock);
      end;
//
//=============> Получаем информацию о температуре GPU <===============
   If ADL_Overdrive6_Temperature_Get(GPU_num, @Temp) = 0 then
    Temperature := Round(0.001 * Temp); // Temp была в милли-градусах C
//
//========> Получаем информацию о скорости вентилятора GPU <===========
   FanSpeedValue.iSize := SizeOf(ADLFanSpeedValue);
   FanSpeedValue.iFlags := ADL_DL_FANCTRL_FLAG_USER_DEFINED_SPEED;
   FanSpeedValue.iSpeedType := ADL_DL_FANCTRL_SPEED_TYPE_PERCENT;
   If ADL_Overdrive5_FanSpeed_Get(GPU_num, 0, @FanSpeedValue) = 0
    then FanSpeed := FanSpeedValue.iFanSpeed;
//
//...... Один раз покажем информацию о памяти на борту GPU-AMD ........
      If ShowMesAMD then begin
      ShowMesAMD := 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.
Ответить с цитированием
  #5  
Старый 03.02.2018, 13:21
vers0 vers0 вне форума
Прохожий
 
Регистрация: 21.12.2013
Адрес: Донецк
Сообщения: 17
Версия Delphi: Delphi 7
Репутация: 10
Вопрос

Доброго времени суток.
Собственно из всей проделанной работы (довольно-таки объемной), меня интересует только 2 значения: температура GPU, скорость вращения куллера GPU (см. скрин).

Цитата:
Сообщение от Prok186
[*] температуры GPU

Можно как-то выделить из Demo только этот кусок? Второй день пытаюсь разобраться с исходниками, но к сожалению я профан.
Также ругается на строку (Undeclared Identifier):
Код:
TypeGPU = (gpuNO = 0,  gpuNVIDIA = 1,  gpuAMD = 2);


Также пишет Undeclared Identifier - Temperature, если прописать на таймер:
Код:
with Label1 do
 begin
   Caption:='GPU Temperature:'+IntToStr(Temperature)+'°C';
 end;
Изображения
Тип файла: png 0000000000.png (16.6 Кбайт, 10 просмотров)

Последний раз редактировалось vers0, 04.02.2018 в 16:04.
Ответить с цитированием
Ответ



Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB-коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход


Часовой пояс GMT +3, время: 02:16.


 

Сайт

Форум

FAQ

RSS лента

Прочее

 

Copyright © Форум "Delphi Sources", 2004-2018

ВКонтакте   Facebook   Twitter