2012-10-22 50 views
5

Tôi có chương trình theo dõi nhiệt độ mà tôi đã viết một thời gian để theo dõi nhiệt độ và quạt trên card đồ họa AMD của tôi, kiểm tra lỗi quạt hoặc quá nóng. Vấn đề với nó, là nó cần phải biết trước đó quá trình sẽ được sử dụng GPU (Graphics Processing Unit), để giết nó hoặc duyên dáng làm cho nó dừng lại để tránh quá nóng.Tôi làm cách nào để sử dụng GPU cho mỗi quá trình?

Để làm cho chương trình của tôi năng động hơn, tôi cần một cách để tìm quy trình nào đang sử dụng GPU, giống như quá trình đang sử dụng thời gian CPU (Trình quản lý Tác vụ). Một ứng dụng như vậy là Process Explorer từ SysInternals.

Tôi hỏi, làm cách nào tôi có thể thực hiện việc này trong Windows trong C? Tôi biết rằng nếu có một cách như vậy, nó sẽ nhắm mục tiêu Vista trở lên.

+0

Còn ứng dụng OpenCL thì sao? Và câu hỏi của bạn là rất nhiều hệ điều hành cụ thể (trên Linux, nó khác với Windows). –

+0

Có, Windows là hệ điều hành mà tôi đang nhắm mục tiêu. Còn ứng dụng OpenCL thì sao? Thực tế là vì OpenCL mà ban đầu tôi đã viết ứng dụng của mình nên GPU/s của tôi không quá nóng. – farmdve

+0

Chỉ cần gợi ý nhanh: xem [Process Hacker] (http://superuser.com/a/585597/297281) C [source code] (https://github.com/processhacker2/processhacker2/search?utf8=% E2% 9C% 93 & q = gpu); có vẻ như các cuộc gọi API số liệu thống kê trực tiếp được sử dụng ở đó. –

Trả lời

1

Nếu bạn có một bảng Tesla hoặc cao cấp Quadro và chạy trên Windows Server 2008 R2 64bit, Windows 7 64bit (hoặc 32/64bit Linux) sau đó bạn có thể sử dụng NVML để làm điều đó.

Tải mới nhất NVML SDK (Tespla Deployment Kit) và hãy nhìn vào hai chức năng:

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

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

Coi chừng:

nvmlReturn_t nvmlDeviceGetFanSpeed (nvmlDevice_t device, unsigned int * speed) 

It "lấy tốc độ hoạt động dự định của người hâm mộ của thiết bị" không tốc độ quạt thật . Vì vậy, bạn không thể sử dụng nó để kiểm tra thất bại của quạt.

Tôi không biết về nvmlDeviceGetComputeRunningProcesses thay thế hoạt động trên bo mạch GeForce, nhưng Windows NvAPI (cũng hoạt động trên GeForce) cho phép truy vấn cả Tốc độ quạt và Nhiệt độ.

0

Bạn cần gọi hàm API direct3d không có giấy tờ D3DKMTQueryStatistics.

Mẫu mã lấy từ 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; 
} 

Nhiều cuộc gọi đến D3DKMTQueryStatistics có thể được lấy mẫu từ mã gpumon.c here.

Các vấn đề liên quan