2012-10-22 5 views
5

Ich habe ein Programm zur Temperaturüberwachung, das ich vor einiger Zeit geschrieben habe. Es überwacht die Temperaturen und Lüfter meiner AMD-Grafikkarten, prüft auf Lüfterausfall oder überhitzt. Das Problem damit ist, dass es im Voraus wissen muss, welcher Prozess die GPU (Graphics Processing Unit) verwenden wird, um es zu stoppen oder es sanft zu stoppen, um eine Überhitzung zu vermeiden.Wie bekomme ich die GPU-Nutzung pro Prozess?

Um mein Programm dynamischer zu machen, musste ich einen Weg finden, welcher Prozess die GPU verwendet, ähnlich wie der Prozess CPU-Zeit verwendet (Task-Manager). Eine solche Anwendung ist der Process Explorer von SysInternals.

Ich frage, wie kann ich das in Windows in C tun? Ich bin mir bewusst, dass es, wenn es so einen Weg gibt, Vista und höher als Ziel haben würde.

+0

Was ist mit OpenCL-Anwendungen? Und Ihre Frage ist stark betriebssystemspezifisch (unter Linux ist das anders als unter Windows). –

+0

Ja, Windows ist das Betriebssystem, auf das ich ausgerichtet bin. Und was ist mit OpenCL-Anwendungen? Es ist in der Tat wegen OpenCL, dass ich anfänglich meine Anwendung geschrieben habe, so dass meine GPU/s nicht überhitzt. – farmdve

+0

Nur ein kurzer Hinweis: siehe [Process Hacker] (http://superuser.com/a/585597/297281) C [Quellcode] (https://github.com/processhacker2/processhacker2/search?utf8=% E2% 9C% 93 & q = GPU); Es sieht so aus, als ob direkte 3D-Statistik-API-Aufrufe dort verwendet werden. –

Antwort

1

Wenn Sie ein Tesla Board oder High-End-Quadro haben und läuft auf Windows Server 2008 R2 64bit, Windows 7 64-Bit- (oder 32/64-Bit-Linux), dann können Sie NVML verwenden, das zu tun.

herunterladen neuesten NVML SDK (Tespla Deployment Kit) und einen Blick auf diese beiden Funktionen übernehmen:

nvmlReturn_t nvmlDeviceGetComputeRunningProcesses (nvmlDevice_t device, 
                unsigned int infoCount, 
                nvmlProcessInfo_t * infos) 

nvmlReturn_t nvmlDeviceGetTemperature (nvmlDevice_t device, 
             nvmlTemperatureSensors_t sensorType, 
             unsigned int * temp) 

Achten Sie auf:

nvmlReturn_t nvmlDeviceGetFanSpeed (nvmlDevice_t device, unsigned int * speed) 

It „ruft die beabsichtigte Betriebsgeschwindigkeit der Lüfter des Geräts“ nicht wirklich Lüftergeschwindigkeit . Sie können es also nicht zum Überprüfen von Lüfterfehlern verwenden.

Ich bin mir nicht bewusst, nvmlDeviceGetComputeRunningProcesses Ersatz, die auf GeForce-Boards funktionieren würde, aber Windows NvAPI (die auch auf GeForce funktioniert) ermöglicht es, Lüftergeschwindigkeit und Temperatur abzufragen.

0

Sie müssten etwas undokumentiert direct3d API-Funktion D3DKMTQueryStatistics aufrufen.

Beispielcode genommen von ProcessHacker forum:

#define _Field_size_(...) 
#define _Field_size_bytes_(...) 
#define _In_reads_bytes_opt_(...) 
#define _Out_writes_bytes_all_opt_(...) 
#define _Field_size_bytes_part_(...) 
#define _In_range_(...) 
#define _Out_writes_bytes_(...) 
#define _Check_return_ 
#define _Inout_ 
#define _In_ 
#define _Out_ 

#define NTDDI_VERSION NTDDI_WIN7 
#include <windows.h> 
#include <tchar.h> 
#include <stdio.h> 
#include "d3dkmthk.h" 

#pragma comment(lib, "gdi32.lib") // Doesn't do much, since it doesn't have the exports anyway... 
#pragma comment(lib, "advapi32.lib") 

typedef NTSTATUS (APIENTRY *PD3DKMTQueryStatistics)(_In_ CONST D3DKMT_QUERYSTATISTICS*); 
typedef NTSTATUS (APIENTRY *PD3DKMTOpenAdapterFromDeviceName)(_Inout_ D3DKMT_OPENADAPTERFROMDEVICENAME*); 

int _tmain(int argc, TCHAR *argv[]) 
{ 
    LUID luid = { 20 }; 
    TOKEN_PRIVILEGES privs = { 1, { luid, SE_PRIVILEGE_ENABLED } }; 
    HANDLE hToken; 
    if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken)) 
    { 
     if (AdjustTokenPrivileges(hToken, FALSE, &privs, sizeof(privs), NULL, NULL)) 
     { 
     } 
     else { return -1; } 
    } 
    else { return -2; } 
    D3DKMT_OPENADAPTERFROMDEVICENAME name = { _T("\\\\?\\pci#ven_10de&dev_0a2b&subsys_9072104d&rev_a2#4&12796cb&0&0008#{1ca05180-a699-450a-9a0c-de4fbe3ddd89}") }; 
    HMODULE hGdi32 = LoadLibrary(_T("gdi32.dll")); 
    PD3DKMTOpenAdapterFromDeviceName D3DKMTOpenAdapterFromDeviceName = (PD3DKMTOpenAdapterFromDeviceName)GetProcAddress(hGdi32, "D3DKMTOpenAdapterFromDeviceName"); 
    NTSTATUS status = D3DKMTOpenAdapterFromDeviceName(&name); 
    if (status == 0) 
    { 
     _tprintf(_T("name.AdapterLuid: %llx\n"), name.AdapterLuid); 
     HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION, TRUE, GetCurrentProcessId()); 
     _tprintf(_T("hProcess: %#p\n"), hProcess); 
     if (hProcess != NULL) 
     { 
      for (;;) 
      { 
       PD3DKMTQueryStatistics D3DKMTQueryStatistics = (PD3DKMTQueryStatistics)GetProcAddress(hGdi32, "D3DKMTQueryStatistics"); 
       D3DKMT_QUERYSTATISTICS stats = { D3DKMT_QUERYSTATISTICS_PROCESS, name.AdapterLuid, hProcess }; 
       status = D3DKMTQueryStatistics(&stats); 
       if (status == 0) 
       { 
        _tprintf(_T("Usage: %#llx\n"), stats.QueryResult.ProcessInformation.SystemMemory.BytesAllocated); 
       } 
       else { break; } 
       fflush(stdout); 
       Sleep(1000); 
      } 
     } 
    } 
    _tprintf(_T("%#x\n"), status); 
    return status; 
} 

Weitere Anrufe D3DKMTQueryStatistics aus gpumon.c Code here abgetastet werden.

Verwandte Themen