1

我正在使用 NVAPI.dll 来更改 gpu 的核心时钟。在 nvapi.dll 中使用 NvAPI_GPU_SetPstates20 函数 nvapi.dll 在 C# 中的结构是这样的:

 [StructLayout(LayoutKind.Explicit, Pack = 8)]
internal struct dataStruct
{
    [FieldOffset(0)]
    public singleStruct single;
    [FieldOffset(0)]
    public rangeStruct range;
}
[StructLayout(LayoutKind.Sequential, Pack = 8)]
internal struct valuerange
{
    public int min;
    public int max;
}
[StructLayout(LayoutKind.Sequential, Pack = 8)]
internal struct NV_GPU_PSTATE20_BASE_VOLTAGE_ENTRY
{
    public uint domainId;
    public uint editable;//1
    public uint reserved;//31
    public uint voltageUV;
    public NV_GPU_PERF_PSTATES20_PARAM_DELTA voltageDeltaUV;
}
[StructLayout(LayoutKind.Sequential, Pack = 8)]
internal struct NV_GPU_PERF_PSTATES20_PARAM_DELTA
{
    public int value;
    public valuerange valueRanges;
}
[StructLayout(LayoutKind.Sequential, Pack = 8)]
internal struct pstateStruct
{
    public uint pStateId;
    public uint editable;//1
    public uint reserved;//31
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
    public NV_GPU_PSTATE20_CLOCK_ENTRY[]clocks;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
    public NV_GPU_PSTATE20_BASE_VOLTAGE_ENTRY[]baseVoltages;
}
[StructLayout(LayoutKind.Sequential, Pack = 8)]
internal struct singleStruct
{
    public uint frequencyKHz;
}
[StructLayout(LayoutKind.Sequential, Pack = 8)]
internal struct rangeStruct
{
    public uint minFrequencyKHz;
    public uint maxFrequencyKHz;
    public uint domainId;
    public uint minVoltageUV;
    public uint maxVoltageUV;
}
[StructLayout(LayoutKind.Sequential, Pack = 8)]
internal struct overVoltageStruct
{
    public uint numVoltages;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 4)]
    public NV_GPU_PSTATE20_BASE_VOLTAGE_ENTRY []voltages;//[4]
}
[StructLayout(LayoutKind.Sequential, Pack = 8)]
internal struct NV_GPU_PSTATE20_CLOCK_ENTRY
{
    public uint domainId;
    public uint typeId;
    public uint editable;//1
    public uint reserved;//31
    public NV_GPU_PERF_PSTATES20_PARAM_DELTA frequencyDeltaKHz;
    public dataStruct data;
    
}
[StructLayout(LayoutKind.Sequential, Pack = 8)]
internal struct NV_GPU_PERF_PSTATES20_INFO
{
    public uint version;
    public uint editable;//1
    public uint reserved;//31
    public uint numPStates;
    public uint numClocks;
    public uint numBaseVoltages;
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]
    public pstateStruct[] pStates;
    public overVoltageStruct overVoltage;
}

这是我的功能:

public static void SetCoreClock(NvPhysicalGpuHandle handle,int clock)
    {

        NV_GPU_PERF_PSTATES20_INFO pStatesInfo=new NV_GPU_PERF_PSTATES20_INFO();
        pStatesInfo.version = (uint) Marshal.SizeOf(typeof(NV_GPU_PERF_PSTATES20_INFO)) | 0x10000;
        pStatesInfo.numPStates = 1;
        pStatesInfo.numClocks = 1;
        pStatesInfo.editable = 1;
        pStatesInfo.reserved = 31;
        pStatesInfo.pStates = new pstateStruct[16];
        pStatesInfo.overVoltage.voltages = new NV_GPU_PSTATE20_BASE_VOLTAGE_ENTRY[4];
        pStatesInfo.pStates[0].baseVoltages = new NV_GPU_PSTATE20_BASE_VOLTAGE_ENTRY[4];
        pStatesInfo.pStates[0].clocks = new NV_GPU_PSTATE20_CLOCK_ENTRY[8];
        pStatesInfo.pStates[0].clocks[0].editable = 1;
        pStatesInfo.pStates[0].clocks[0].reserved = 31;
        pStatesInfo.pStates[0].pStateId = 0;
        pStatesInfo.pStates[0].clocks[0].domainId = 0;
        pStatesInfo.pStates[0].clocks[0].typeId = 0;
        pStatesInfo.pStates[0].clocks[0].frequencyDeltaKHz.value = clock;
        pStatesInfo.pStates[0].clocks[0].frequencyDeltaKHz.valueRanges.max = 0;
        pStatesInfo.pStates[0].clocks[0].frequencyDeltaKHz.valueRanges.min = 0;
        a = NVAPI.NvAPI_GPU_SetPstates20(handle,ref pStatesInfo);
    }

当我运行函数“SetCoreClock”时。值 a 返回“INCOMPATIBLE_STRUCT_VERSION”。我的结构错了吗?我找到了一个 C++ 代码。代码的结构是:

struct NV_GPU_PERF_PSTATES20_PARAM_DELTA
{
    int value;

    struct
    {
        int min;
        int max;
    } valueRange;
};

struct NV_GPU_PSTATE20_BASE_VOLTAGE_ENTRY
{
    unsigned int domainId;
    unsigned int editable : 1;
    unsigned int reserved : 31;
    unsigned int voltageUV;
    NV_GPU_PERF_PSTATES20_PARAM_DELTA voltageDeltaUV;
};

struct NV_GPU_PSTATE20_CLOCK_ENTRY
{
    unsigned int domainId;
    unsigned int typeId;
    unsigned int editable : 1;
    unsigned int reserved : 31;
    NV_GPU_PERF_PSTATES20_PARAM_DELTA frequencyDeltaKHz;

    union
    {
        struct
        {
            unsigned int frequencyKHz;
        } single;

        struct
        {
            unsigned int minFrequencyKHz;
            unsigned int maxFrequencyKHz;
            unsigned int domainId;
            unsigned int minVoltageUV;
            unsigned int maxVoltageUV;
        } range;
    } data;
};

struct NV_GPU_PERF_PSTATES20_INFO
{
    unsigned int version;
    unsigned int editable : 1;
    unsigned int reserved : 31;
    unsigned int numPStates;
    unsigned int numClocks;
    unsigned int numBaseVoltages;

    struct
    {
        unsigned int pStateId;
        unsigned int editable : 1;
        unsigned int reserved : 31;
        NV_GPU_PSTATE20_CLOCK_ENTRY clocks[8];
        NV_GPU_PSTATE20_BASE_VOLTAGE_ENTRY baseVoltages[4];
    } pStates[16];

    struct
    {
        unsigned int numVoltages;
        NV_GPU_PSTATE20_BASE_VOLTAGE_ENTRY voltages[4];
    } overVoltage;
};```
Thanks for helping me solved the problem.
4

1 回答 1

0

这意味着您的结构大小不正确。我发现的一个例子说版本应该是0x11c94. 保留恕我直言之类的东西需要删除。我有同样的问题,我这样做是为了找到版本:

uint GPUVER3 = (uint)Marshal.SizeOf(typeof(NV_GPU_PERF_PSTATES20_INFO_V1)) | 0x20000;

0x11c94一旦你得到与它应该工作的版本相同的版本。

我用来解决这个问题的 C 代码

https://github.com/suppai/nvidia-overclock

于 2022-01-06T14:05:58.490 回答