nvmlDeviceGetMinMaxClockOfPState and nvmlDeviceGetMaxClockInfo take disproportionate amount of CPU time in 570


Please fix.

Isn’t fixed in 570.124.04.

Still isn’t fixed in 575.

Still not fixed.

Can you please include some more information such as:

  • What OS you’re using
  • What GPU you’re using
  • How you are calling the APIs

OS: Linux
GPU: 4060

NVMLGPUPstateClocksAttribute code:

package com.bluegoliath.envious.nvml.local.attributes.performance;

import com.bluegoliath.bindings.nvml.enums.nvmlClockType_t;
import com.bluegoliath.bindings.nvml.enums.nvmlReturn_t;
import com.bluegoliath.envious.nvml.local.internal.NVMLLocalGPUInternal;
import com.bluegoliath.bindings.nvml.enums.nvmlPstates_t;
import com.bluegoliath.bindings.nvml.nvml_h;
import com.bluegoliath.crosspoint.fma.values.NativeInt32;
import com.bluegoliath.envious.base.abstracts.internal.NVAttributeGenericBase;
import com.bluegoliath.envious.base.enums.Unit;
import com.bluegoliath.envious.base.meta.NVNumberAttributeMeta;
import com.bluegoliath.envious.nvml.local.internal.NVMLContextInternal;
import com.bluegoliath.oroc.interfaces.EnumStringProvider;
import com.bluegoliath.oroc.interfaces.NumberReadable;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

public class NVMLGPUPstateClocksAttribute extends NVAttributeGenericBase<nvmlReturn_t, NVMLLocalGPUInternal>
{
    private final NVNumberAttributeMeta<Integer, nvmlReturn_t, NVMLLocalGPUInternal> minAttribute;
    private final NVNumberAttributeMeta<Integer, nvmlReturn_t, NVMLLocalGPUInternal> maxAttribute;
    
    private final NativeInt32 minPointer;
    private final NativeInt32 maxPointer;
    
    private final nvmlPstates_t state;
    private final nvmlClockType_t type;
    
    public NVMLGPUPstateClocksAttribute(NVMLLocalGPUInternal gpu, nvmlPstates_t state, nvmlClockType_t type, EnumStringProvider<nvmlPstates_t> stateProvider, EnumStringProvider<nvmlClockType_t> typeProvider)
    {
        super(gpu, "Performance State Min/Max Clocks Meta");
        
        this.state = state;
        this.type = type;
        
        List<String> contextualStrings = List.of(
                gpu.getNVDevice().get().toString(),
                stateProvider.getResultString(state),
                typeProvider.getResultString(type)
        );
        
        this.minAttribute = new NVNumberAttributeMeta<>(
                this,
                "Clock Min",
                Unit.MEGAHERTZ,
                "Lowest clock of this performance state's clock type.",
                contextualStrings);

        this.maxAttribute = new NVNumberAttributeMeta<>(
                this,
                "Clock Max",
                Unit.MEGAHERTZ,
                "Highest clock of this performance state's clock type."
                + "\n\n"
                + "All max clocks besides memory may be inaccurate for a variety of reasons.",
                contextualStrings);

        this.minPointer = gpu.getAccountingAllocator().newNativeValue(NativeInt32.METADATA);
        this.maxPointer = gpu.getAccountingAllocator().newNativeValue(NativeInt32.METADATA);
    }
    
    @Override
    public nvmlReturn_t update()
    {
        long startTime = System.currentTimeMillis();

        nvmlReturn_t returnValue = nvml_h.INSTANCE.nvmlDeviceGetMinMaxClockOfPState(
                super.getNVDevice().get().getNativePointer(),
                this.type,
                this.state,
                this.minPointer,
                this.maxPointer);

        if(!this.getSuccessReturnValue().equals(returnValue))
        {
            super.finishUpdate(returnValue, System.currentTimeMillis() - startTime);
            return returnValue;
        }
            
        this.minAttribute.setValueDirect(this.minPointer.get());
        this.maxAttribute.setValueDirect(this.maxPointer.get());

        super.finishUpdate(returnValue, System.currentTimeMillis() - startTime);
        
        return returnValue;
    }
    
    public NumberReadable<Integer, nvmlReturn_t> getMin()
    {
        return this.minAttribute;
    }
    
    public NumberReadable<Integer, nvmlReturn_t> getMax()
    {
        return this.maxAttribute;
    }
    
    @Override
    public nvmlReturn_t getSuccessReturnValue()
    {
        return nvmlReturn_t.NVML_SUCCESS;
    }
    
    @Override
    public String getReturnString(nvmlReturn_t value)
    {
        return NVMLContextInternal.toString(value);
    }
    
    @Override
    public List<nvmlReturn_t> getReturnValues()
    {
        return List.of(
                nvmlReturn_t.NVML_SUCCESS,
                nvmlReturn_t.NVML_ERROR_UNINITALIZED,
                nvmlReturn_t.NVML_ERROR_INVALID_ARGUMENT,
                nvmlReturn_t.NVML_ERROR_NOT_SUPPORTED);
    }
}

NVMLGPUClockMaxAttribute code:

package com.bluegoliath.envious.nvml.local.attributes.clocks;

import java.util.List;
import java.util.Optional;
import com.bluegoliath.bindings.nvml.enums.nvmlClockType_t;
import com.bluegoliath.bindings.nvml.enums.nvmlReturn_t;
import com.bluegoliath.bindings.nvml.nvml_h;
import com.bluegoliath.envious.base.enums.Unit;
import com.bluegoliath.envious.nvml.local.internal.NVMLLocalGPUInternal;
import com.bluegoliath.crosspoint.fma.values.NativeInt32;
import com.bluegoliath.envious.base.abstracts.internal.NVNumberAttributeGenericBase;
import com.bluegoliath.envious.nvml.local.internal.NVMLContextInternal;
import com.bluegoliath.oroc.interfaces.EnumStringProvider;

public class NVMLGPUClockMaxAttribute extends NVNumberAttributeGenericBase<Integer, nvmlReturn_t, NVMLLocalGPUInternal>
{
    private final NativeInt32 valuePointer;
    
    private final nvmlClockType_t type;
    
    private final String description;
    
    private final EnumStringProvider<nvmlClockType_t> provider;
    
    public NVMLGPUClockMaxAttribute(NVMLLocalGPUInternal gpu, nvmlClockType_t type, String description, EnumStringProvider<nvmlClockType_t> provider)
    {
        super(gpu, "Clock Max", Unit.MEGAHERTZ);
        
        this.valuePointer = gpu.getAccountingAllocator().newNativeValue(NativeInt32.METADATA);
        
        this.type = type;
        this.description = description;
        this.provider = provider;
    }
    
    @Override
    public nvmlReturn_t update()
    {
        long startTime = System.currentTimeMillis();
        
        nvmlReturn_t returnValue = nvml_h.INSTANCE.nvmlDeviceGetMaxClockInfo(
                super.getNVDevice().get().getNativePointer(),
                this.type,
                this.valuePointer);
        
        super.finishUpdate(returnValue, this.valuePointer.intValue(), System.currentTimeMillis() - startTime);
        
        return returnValue;
    }
    
    @Override
    public nvmlReturn_t getSuccessReturnValue()
    {
        return nvmlReturn_t.NVML_SUCCESS;
    }
    
    @Override
    public String getReturnString(nvmlReturn_t value)
    {
        return NVMLContextInternal.toString(value);
    }
    
    @Override
    public Optional<String> getDescription()
    {
        return Optional.of(this.description);
    }
    
    @Override
    public Optional<String> getContextualString(int index)
    {
        switch(index)
        {
            case 0:
                return Optional.of(this.getNVDevice().get().toString());
            case 1:
                return Optional.of(this.provider.getResultString(this.type));
            default:
                return Optional.empty();
        }
    }
    
    @Override
    public List<nvmlReturn_t> getReturnValues()
    {
        return List.of(
                nvmlReturn_t.NVML_SUCCESS,
                nvmlReturn_t.NVML_ERROR_UNINITALIZED,
                nvmlReturn_t.NVML_ERROR_INVALID_ARGUMENT,
                nvmlReturn_t.NVML_ERROR_NOT_SUPPORTED,
                nvmlReturn_t.NVML_ERROR_GPU_IS_LOST,
                nvmlReturn_t.NVML_ERROR_UNKNOWN);
    }
}

Can you please look at nvmlDeviceGetDisplayMode too? It has similar CPU time issues like NVMLGPUClockMaxAttribute.

Code:

package com.bluegoliath.envious.nvml.local.attributes.display;

import java.util.List;
import java.util.Optional;
import com.bluegoliath.bindings.nvml.enums.nvmlEnableState_t;
import com.bluegoliath.bindings.nvml.enums.nvmlReturn_t;
import com.bluegoliath.bindings.nvml.nvml_h;
import com.bluegoliath.crosspoint.fma.interfaces.metadata.NativeEnumData;
import com.bluegoliath.crosspoint.fma.values.NativeEnum32;
import com.bluegoliath.envious.base.abstracts.internal.NVEnumAttributeGenericBase;
import com.bluegoliath.envious.nvml.local.internal.NVMLContextInternal;
import com.bluegoliath.envious.nvml.local.internal.NVMLLocalGPUInternal;

public class NVMLGPUDisplayModeAttribute extends NVEnumAttributeGenericBase<nvmlEnableState_t, nvmlReturn_t, NVMLLocalGPUInternal>
{
    private final NativeEnum32<nvmlEnableState_t> valuePointer;
    
    public NVMLGPUDisplayModeAttribute(NVMLLocalGPUInternal gpu)
    {
        super(gpu, "Display Mode");
        
        this.valuePointer = gpu.getAccountingAllocator().newNativeValue(
                NativeEnum32.METADATA.withInstance(nvmlEnableState_t.DISABLED));
    }
    
    @Override
    public nvmlReturn_t update()
    {
        long startTime = System.currentTimeMillis();
        
        nvmlReturn_t returnValue = nvml_h.INSTANCE.nvmlDeviceGetDisplayMode(
                super.getNVDevice().get().getNativePointer(),
                this.valuePointer);
        
        super.finishUpdate(returnValue, this.valuePointer.get(), System.currentTimeMillis() - startTime);
        
        return returnValue;
    }
    
    @Override
    public nvmlReturn_t getSuccessReturnValue()
    {
        return nvmlReturn_t.NVML_SUCCESS;
    }

    @Override
    public String getResultString(nvmlEnableState_t value)
    {
        return NVMLContextInternal.toString(value);
    }
    
    @Override
    public String getReturnString(nvmlReturn_t value)
    {
        return NVMLContextInternal.toString(value);
    }
    
    @Override
    public Optional<String> getDescription()
    {
        return Optional.of(
        "Indicates whether a physical display is connected to the GPU.");
    }
    
    @Override
    public List<nvmlReturn_t> getReturnValues()
    {
        return List.of(
                nvmlReturn_t.NVML_SUCCESS,
                nvmlReturn_t.NVML_ERROR_UNINITALIZED,
                nvmlReturn_t.NVML_ERROR_INVALID_ARGUMENT,
                nvmlReturn_t.NVML_ERROR_NOT_SUPPORTED,
                nvmlReturn_t.NVML_ERROR_GPU_IS_LOST,
                nvmlReturn_t.NVML_ERROR_UNKNOWN);
    }
}