c++ 是否有任何API可以获取英特尔Arc显卡的GPU活动?我需要通过编程

von4xj4u  于 2023-10-20  发布在  其他
关注(0)|答案(1)|浏览(214)

我在一个C#的Windows应用程序中工作,它将显示离散卡相关的信息,如GPU活动,GPU风扇和温度参数等。对于NVIDIA,AMD,我们有NVAPI和ATL。但对于情报,我不知道。
对于Intel arc卡,我可以从Intel IGCL获取内存大小,GPU风扇,温度等参数。但是对于GPU活动和内存活动,OpenCL usageI无法在其中找到合适的方法/结构。
是否有其他可用的c++ API提供这些细节?或任何低级API?
如果有人知道这件事
以前对于集成显卡,有一个名为D3DKMT_ESCAPE的结构,它将返回视频使用,开放CL使用,GPU活动等参数值。由于英特尔停止支持D3DKMT_ESCAPE和英特尔Arc卡是新的,我找不到他们。
我尝试得到的是,g->PStateUtil_GPU = pDynamicPStatesInfo.utilization[0].percentage;-->返回NVIDIA卡的GPU活动百分比。我想为英特尔获得类似的价值

knpiaxh1

knpiaxh11#

您还可以从IGCL C++ API获取GPU/内存活动。
将文件igcl_api.hcApiWrapper.cpp下载到源代码中。下面是一个快速和肮脏的最小示例,关于如何获得GPU/VRAM使用率,VRAM带宽使用率,时钟速度,温度和风扇速度。更详细的例子,请看here

string gpu_name; // GPU name
uint gpu_usage; // GPU usage in %
uint gpu_memory, gpu_memory_used, gpu_memory_max; // VRAM usage in % and MB
uint gpu_memory_bandwidth, gpu_memory_bandwidth_used, gpu_memory_bandwidth_max; // in % and MB/s
uint gpu_temp, gpu_fan; // in °C and RPM
uint gpu_clock_core; // GPU core clock in MHz

#include "cApiWrapper.cpp"

ctl_device_adapter_handle_t igcl_device;
uint64_t igcl_timestamp_last_activeTime = 0ull;
uint64_t igcl_timestamp_last_timestamp = 0ull;
uint64_t igcl_read_write_counter = 0ull;
uint64_t igcl_timestamp_last_bandwidth = 0ull;

void initialize_gpu_data() {
    ctl_device_adapter_handle_t* igcl_devices = nullptr;
    uint igcl_device_number = 0;
    ctl_init_args_t init_args;
    ctl_api_handle_t api_handle;
    init_args.AppVersion = CTL_MAKE_VERSION(CTL_IMPL_MAJOR_VERSION, CTL_IMPL_MINOR_VERSION);
    init_args.flags = CTL_INIT_FLAG_USE_LEVEL_ZERO;
    init_args.Size = sizeof(init_args);
    init_args.Version = 0;
    ZeroMemory(&init_args.ApplicationUID, sizeof(ctl_application_id_t));
    do {
        ctl_result_t igcl_device_exists = ctlInit(&init_args, &api_handle);
        if(igcl_device_exists==CTL_RESULT_SUCCESS) {
            igcl_device_exists = ctlEnumerateDevices(api_handle, &igcl_device_number, igcl_devices);
            if(igcl_device_exists==CTL_RESULT_SUCCESS) {
                igcl_devices = (ctl_device_adapter_handle_t*)malloc(sizeof(ctl_device_adapter_handle_t) * igcl_device_number);
                igcl_device_exists = ctlEnumerateDevices(api_handle, &igcl_device_number, igcl_devices);
            }
        }
    } while(igcl_device_number<1u);
    igcl_device = igcl_devices[0];
    {
        ctl_device_adapter_properties_t deviceadapterproperties = { 0 };
        deviceadapterproperties.Size = sizeof(ctl_device_adapter_properties_t);
        deviceadapterproperties.pDeviceID = malloc(sizeof(LUID));
        deviceadapterproperties.device_id_size = sizeof(LUID);
        deviceadapterproperties.Version = 2;
        ctlGetDeviceProperties(igcl_device, &deviceadapterproperties);
        gpu_name = deviceadapterproperties.name;
    }
}

void query_gpu_data() {
    {
        uint engine_count = 0u;
        ctlEnumEngineGroups(igcl_device, &engine_count, nullptr);
        ctl_engine_handle_t* engines = new ctl_engine_handle_t[engine_count];
        ctlEnumEngineGroups(igcl_device, &engine_count, engines);
        for(uint i=0u; i<engine_count; i++) {
            ctl_engine_properties_t engine_properties = { 0 };
            engine_properties.Size = sizeof(ctl_engine_properties_t);
            ctlEngineGetProperties(engines[i], &engine_properties);
            if(engine_properties.type==CTL_ENGINE_GROUP_RENDER) { // CTL_ENGINE_GROUP_MEDIA
                ctl_engine_stats_t engine_stats = { 0 };
                engine_stats.Size = sizeof(ctl_engine_stats_t);
                ctlEngineGetActivity(engines[i], &engine_stats);
                gpu_usage = to_uint(100.0f*(float)(engine_stats.activeTime-igcl_timestamp_last_activeTime)/(float)(engine_stats.timestamp-igcl_timestamp_last_timestamp));
                igcl_timestamp_last_activeTime = engine_stats.activeTime;
                igcl_timestamp_last_timestamp = engine_stats.timestamp;
            }
        }
        delete[] engines;
    } {
        uint memory_count = 0u;
        ctlEnumMemoryModules(igcl_device, &memory_count, nullptr);
        ctl_mem_handle_t* memory_handle = new ctl_mem_handle_t[memory_count];
        ctlEnumMemoryModules(igcl_device, &memory_count, memory_handle);
        for(uint i=0u; i<min(memory_count, 1u); i++) {
            ctl_mem_state_t state = { 0 };
            state.Size = sizeof(ctl_mem_state_t);
            ctlMemoryGetState(memory_handle[i], &state);
            gpu_memory_used = (uint)((state.size-state.free)/1048576ull);
            gpu_memory_max = (uint)(state.free/1048576ull);
            gpu_memory = to_uint(100.0f*(float)(state.size-state.free)/(float)state.size);
            ctl_mem_bandwidth_t bandwidth = { 0 };
            bandwidth.Version = 1;
            bandwidth.Size = sizeof(ctl_mem_bandwidth_t);
            ctlMemoryGetBandwidth(memory_handle[i], &bandwidth);
            gpu_memory_bandwidth_used = (uint)(((bandwidth.readCounter+bandwidth.writeCounter-igcl_read_write_counter))/(bandwidth.timestamp-igcl_timestamp_last_bandwidth)); // does not work
            gpu_memory_bandwidth_max =(uint)(bandwidth.maxBandwidth/1000000ull);
            gpu_memory_bandwidth = to_uint(100.0f*(float)gpu_memory_bandwidth_used/(float)gpu_memory_bandwidth_max);
            igcl_read_write_counter = bandwidth.readCounter+bandwidth.writeCounter;
            igcl_timestamp_last_bandwidth = bandwidth.timestamp;
        }
        delete[] memory_handle;
    } {
        ctl_power_telemetry_t power_telemetry = { 0 };
        power_telemetry.Size = sizeof(ctl_power_telemetry_t);
        ctlPowerTelemetryGet(igcl_device, &power_telemetry);
        gpu_temp = to_uint(power_telemetry.gpuCurrentTemperature.value.datadouble);
        gpu_fan = to_uint(power_telemetry.fanSpeed[0].value.datadouble);
        gpu_clock_core = to_uint(power_telemetry.gpuCurrentClockFrequency.value.datadouble);
    }
}

相关问题