Delphi Programming Forum
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
델파이 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
컴포넌트/라이브러리
FreePascal/Lazarus
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
델마당
볼랜드포럼 광고 모집

델파이 Q&A
Delphi Programming Q&A
[15893] Re:GPU상태를 알 수 있을까요?
빌더(TWx) [builder] 256 읽음    2017-06-24 22:12
첫눈 님이 쓰신 글 :
: 그래픽카드가 2개 꼽혀 있는데요.
: 각각의 상태를 주기적으로 확인하려 합니다.
: 현제 GPU가 멈춰있는지, 일을 하고 있는지, 죽어버렸는지 확인할 수 있는 방법이 있을까요?


GPU 벤더마다 제공하는 API가 따로 있어요.

NVIDIA의 경우에는...

using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Text;

namespace Hardware.Nvidia {

  public enum NvStatus {
    OK = 0,
    ERROR = -1,
    LIBRARY_NOT_FOUND = -2,
    NO_IMPLEMENTATION = -3,
    API_NOT_INTIALIZED = -4,
    INVALID_ARGUMENT = -5,
    NVIDIA_DEVICE_NOT_FOUND = -6,
    END_ENUMERATION = -7,
    INVALID_HANDLE = -8,
    INCOMPATIBLE_STRUCT_VERSION = -9,
    HANDLE_INVALIDATED = -10,
    OPENGL_CONTEXT_NOT_CURRENT = -11,
    NO_GL_EXPERT = -12,
    INSTRUMENTATION_DISABLED = -13,
    EXPECTED_LOGICAL_GPU_HANDLE = -100,
    EXPECTED_PHYSICAL_GPU_HANDLE = -101,
    EXPECTED_DISPLAY_HANDLE = -102,
    INVALID_COMBINATION = -103,
    NOT_SUPPORTED = -104,
    PORTID_NOT_FOUND = -105,
    EXPECTED_UNATTACHED_DISPLAY_HANDLE = -106,
    INVALID_PERF_LEVEL = -107,
    DEVICE_BUSY = -108,
    NV_PERSIST_FILE_NOT_FOUND = -109,
    PERSIST_DATA_NOT_FOUND = -110,
    EXPECTED_TV_DISPLAY = -111,
    EXPECTED_TV_DISPLAY_ON_DCONNECTOR = -112,
    NO_ACTIVE_SLI_TOPOLOGY = -113,
    SLI_RENDERING_MODE_NOTALLOWED = -114,
    EXPECTED_DIGITAL_FLAT_PANEL = -115,
    ARGUMENT_EXCEED_MAX_SIZE = -116,
    DEVICE_SWITCHING_NOT_ALLOWED = -117,
    TESTING_CLOCKS_NOT_SUPPORTED = -118,
    UNKNOWN_UNDERSCAN_CONFIG = -119,
    TIMEOUT_RECONFIGURING_GPU_TOPO = -120,
    DATA_NOT_FOUND = -121,
    EXPECTED_ANALOG_DISPLAY = -122,
    NO_VIDLINK = -123,
    REQUIRES_REBOOT = -124,
    INVALID_HYBRID_MODE = -125,
    MIXED_TARGET_TYPES = -126,
    SYSWOW64_NOT_SUPPORTED = -127,
    IMPLICIT_SET_GPU_TOPOLOGY_CHANGE_NOT_ALLOWED = -128,
    REQUEST_USER_TO_CLOSE_NON_MIGRATABLE_APPS = -129,
    OUT_OF_MEMORY = -130,
    WAS_STILL_DRAWING = -131,
    FILE_NOT_FOUND = -132,
    TOO_MANY_UNIQUE_STATE_OBJECTS = -133,
    INVALID_CALL = -134,
    D3D10_1_LIBRARY_NOT_FOUND = -135,
    FUNCTION_NOT_FOUND = -136
  } 

  public enum NvThermalController {
    NONE = 0,
    GPU_INTERNAL, 
    ADM1032,
    MAX6649,      
    MAX1617,     
    LM99,     
    LM89,        
    LM64,        
    ADT7473,
    SBMAX6649,
    VBIOSEVT, 
    OS,   
    UNKNOWN = -1,
  }

  public enum NvThermalTarget {
    NONE = 0,
    GPU = 1,
    MEMORY = 2,
    POWER_SUPPLY = 4,
    BOARD = 8,
    ALL = 15,
    UNKNOWN = -1
  };

  [StructLayout(LayoutKind.Sequential, Pack = 8)]
  public struct NvSensor {
    public NvThermalController Controller;
    public int DefaultMinTemp;
    public int DefaultMaxTemp;
    public int CurrentTemp;
    public NvThermalTarget Target;    
  }

  [StructLayout(LayoutKind.Sequential, Pack = 8)]
  public struct NvGPUThermalSettings {
    public int Version;
    public int Count;
    [MarshalAs(UnmanagedType.ByValArray,
      SizeConst = NVAPI.MAX_THERMAL_SENSORS_PER_GPU)]
    public NvSensor[] Sensor;
  }

  [StructLayout(LayoutKind.Sequential)]
  public struct NvDisplayHandle {
    private IntPtr ptr;
  }

  [StructLayout(LayoutKind.Sequential)]
  public struct NvPhysicalGpuHandle {
    private IntPtr ptr;
  }

  public class NVAPI {
         
    private const int SHORT_STRING_MAX = 64;

    public const int MAX_THERMAL_SENSORS_PER_GPU = 3;
    public const int MAX_PHYSICAL_GPUS = 64;
    public static readonly int GPU_THERMAL_SETTINGS_VER =
      Marshal.SizeOf(typeof(NvGPUThermalSettings)) | 0x10000;
           
    private delegate IntPtr nvapi_QueryInterfaceDelegate(uint id);
    private delegate NvStatus NvAPI_InitializeDelegate();
    private delegate NvStatus NvAPI_GPU_GetFullNameDelegate(
      NvPhysicalGpuHandle gpuHandle, StringBuilder name);

    public delegate NvStatus NvAPI_GPU_GetThermalSettingsDelegate(
      NvPhysicalGpuHandle gpuHandle, int sensorIndex,
      ref NvGPUThermalSettings nvGPUThermalSettings);
    public delegate NvStatus NvAPI_EnumNvidiaDisplayHandleDelegate(int thisEnum,
      ref NvDisplayHandle displayHandle);
    public delegate NvStatus NvAPI_GetPhysicalGPUsFromDisplayDelegate(
      NvDisplayHandle displayHandle, [Out] NvPhysicalGpuHandle[] gpuHandles,
      out int gpuCount);
    public delegate NvStatus NvAPI_EnumPhysicalGPUsDelegate(
      [Out] NvPhysicalGpuHandle[] gpuHandles, out int gpuCount);
    public delegate NvStatus NvAPI_GPU_GetTachReadingDelegate(
      NvPhysicalGpuHandle gpuHandle, out int value);

    private static bool available = false;
    private static nvapi_QueryInterfaceDelegate nvapi_QueryInterface;
    private static NvAPI_InitializeDelegate NvAPI_Initialize;
    private static NvAPI_GPU_GetFullNameDelegate _NvAPI_GPU_GetFullName;

    public static NvAPI_GPU_GetThermalSettingsDelegate
      NvAPI_GPU_GetThermalSettings;
    public static NvAPI_EnumNvidiaDisplayHandleDelegate
      NvAPI_EnumNvidiaDisplayHandle;
    public static NvAPI_GetPhysicalGPUsFromDisplayDelegate
      NvAPI_GetPhysicalGPUsFromDisplay;
    public static NvAPI_EnumPhysicalGPUsDelegate
      NvAPI_EnumPhysicalGPUs;
    public static NvAPI_GPU_GetTachReadingDelegate
      NvAPI_GPU_GetTachReading;

    public static NvStatus NvAPI_GPU_GetFullName(NvPhysicalGpuHandle gpuHandle,
      out string name) {
      StringBuilder builder = new StringBuilder(SHORT_STRING_MAX);
      NvStatus status = _NvAPI_GPU_GetFullName(gpuHandle, builder);
      name = builder.ToString();
      return status;
    }

    private static string GetDllName() {
      if (IntPtr.Size == 4) {
        return "nvapi.dll";
      } else {
        return "nvapi64.dll";
      }
    }

    private static void GetDelegate<T>(uint id, out T newDelegate)
      where T : class
    {
      IntPtr ptr = nvapi_QueryInterface(id);
      if (ptr != IntPtr.Zero) {
        newDelegate =
          Marshal.GetDelegateForFunctionPointer(ptr, typeof(T)) as T;
      } else {
        newDelegate = null;
      }
    }

    static NVAPI() {
      DllImportAttribute attribute = new DllImportAttribute(GetDllName());
      attribute.CallingConvention = CallingConvention.Cdecl;
      attribute.PreserveSig = true;
      attribute.EntryPoint = "nvapi_QueryInterface";
      PInvokeDelegateFactory.CreateDelegate(attribute,
        out nvapi_QueryInterface);

      try {
        GetDelegate(0x0150E828, out NvAPI_Initialize);
      } catch (DllNotFoundException) { return; }
        catch (ArgumentNullException) { return; }

      if (NvAPI_Initialize() == NvStatus.OK) {
        GetDelegate(0xE3640A56, out NvAPI_GPU_GetThermalSettings);
        GetDelegate(0xCEEE8E9F, out _NvAPI_GPU_GetFullName);
        GetDelegate(0x9ABDD40D, out NvAPI_EnumNvidiaDisplayHandle);
        GetDelegate(0x34EF9506, out NvAPI_GetPhysicalGPUsFromDisplay);
        GetDelegate(0xE5AC921F, out NvAPI_EnumPhysicalGPUs);
        GetDelegate(0x5F608315, out NvAPI_GPU_GetTachReading);       
        available = true;
      }
    }

    public static bool IsAvailable {
      get { return available; }
    }

  }
}

+ -

관련 글 리스트
15892 GPU상태를 알 수 있을까요? 첫눈 227 2017-06-19
15893     Re:GPU상태를 알 수 있을까요? 빌더(TWx) 256 2017-06-24
15895         Re:Re:답변 감사합니다. 첫눈 123 2017-07-12
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.