繁体   English   中英

如何使用Nvidia的Performance Toolkit执行“简化的实验”?

[英]How do I perform a 'simplified experiment' with Nvidia's Performance Toolkit?

我正在尝试使用Nvidia的性能工具包来确定OpenGL应用程序中的性能瓶颈。 根据用户指南和提供的示例,我得到了以下代码:

// ********************************************************
// Set up NVPMAPI
#define NVPM_INITGUID
#include "NvPmApi.Manager.h"
// Simple singleton implementation for grabbing the NvPmApi
static NvPmApiManager S_NVPMManager;
NvPmApiManager *GetNvPmApiManager() { return &S_NVPMManager; }
const NvPmApi* getNvPmApi() { return S_NVPMManager.Api(); }

void MyApp::profiledRender()
{
    NVPMRESULT nvResult;

    nvResult = GetNvPmApiManager()->Construct(L"C:\\Program Files\\PerfKit_4.1.0.14260\\bin\\win7_x64\\NvPmApi.Core.dll");
    if (nvResult != S_OK)
    {
        return; // This is an error condition
    }

    auto api = getNvPmApi();

    nvResult = api->Init();
    if ((nvResult) != NVPM_OK)
    {
        return; // This is an error condition
    }

    NVPMContext context;
    nvResult = api->CreateContextFromOGLContext((uint64_t)::wglGetCurrentContext(), &context);
    if (nvResult != NVPM_OK)
    {
        return; // This is an error condition
    }

    api->AddCounterByName(context, "GPU Bottleneck");

    NVPMUINT nCount(1);
    api->BeginExperiment(context, &nCount);
    for (NVPMUINT i = 0; i < nCount; i++) {
        api->BeginPass(context, i);

        render();
        glFinish();

        api->EndPass(context, i);
    }
    api->EndExperiment(context);

    NVPMUINT64 bottleneckUnitId(42424242);
    NVPMUINT64 bottleneckCycles(42424242);
    api->GetCounterValueByName(context, "GPU Bottleneck", 0, &bottleneckUnitId, &bottleneckCycles);
    char name[256] = { 0 };
    NVPMUINT length = 0;
    api->GetCounterName(bottleneckUnitId, name, &length);
    NVPMUINT64 counterValue(42424242), counterCycles(42424242);
    api->GetCounterValue(context, bottleneckUnitId, 0, &counterValue, &counterCycles);

    std::cout << "--- NVIDIA Performance Kit GPU profile ---\n"
        "bottleneckUnitId: " << bottleneckUnitId 
        << ", bottleneckCycles: " << bottleneckCycles 
        << ", unit name: " << name
        << ", unit value: " << counterValue
        << ", unit cycles: " << counterCycles
        << std::endl;
}

但是,打印输出显示我的所有整数值均未修改:

--- NVIDIA Performance Kit GPU profile ---
bottleneckUnitId: 42424242, bottleneckCycles: 42424242, unit name: , unit value:
 42424242, unit cycles: 42424242

我在调用profiledRender以及在api->CreateContextFromOGLContext((uint64_t)::wglGetCurrentContext(), &context);时处于有效的GL上下文中api->CreateContextFromOGLContext((uint64_t)::wglGetCurrentContext(), &context); 看起来有点狡猾,它确实会返回OK结果(而为上下文传递0将返回not OK结果,而放入随机数将导致访问冲突)。

这是针对Windows 8.1上在x64中运行的Cinder 0.8.6构建的。 打开GL 4.4,GeForce GT 750M。

好了,对API返回代码进行了更持久的分析,并进一步检查了手册,发现了问题所在。

  1. 渲染调用需要包装在api->BeginObject(context, 0); api->EndObject(context, 0); 这给了我们一个瓶颈UnitId。

  2. 似乎传递给GetCounterNamelength指针既指示char数组的大小作为输入,也写入字符串长度作为输出。 这在反射时很明显,但是是从用户指南示例中复制的一个错误。 这给了我们瓶颈的名称。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM