首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >并发产生的DXGI_ERROR_DEVICE_HUNG::复制到C++ AMP

并发产生的DXGI_ERROR_DEVICE_HUNG::复制到C++ AMP
EN

Stack Overflow用户
提问于 2015-04-25 00:29:55
回答 1查看 1.2K关注 0票数 1

我已经创建了一些C++ AMP代码,以执行背景梯度去除天文图像。它们作为RGB的16位无符号整数出现。我的应用程序的所有处理和输出都是以单精度浮点进行的,因此我转换输入数据,运行C++ AMP代码,然后将结果复制回CPU (实际上,在复制回GPU之前,图像将经过GPU上的许多C++ AMP过滤器,但是对于这个测试代码,我已经将其隔离到一个这样的过滤器中。

一切都进行得很顺利,直到我启动并发性::copy操作,将数据从GPU数组复制回CPU。该操作抛出一个异常,指示由于DXGI_ERROR_DEVICE_HUNG而触发了TDR。完全错误是:

D3D11错误: ID3D11Device::RemoveDevice:设备删除是由于以下原因触发的(DXGI_ERROR_DEVICE_HUNG:设备执行命令花费了不合理的时间,或者硬件崩溃/挂起)。因此,触发了TDR (超时值检测和恢复)机制。挂起时,当前设备上下文正在执行命令。应用程序可能希望重新出现并退回到不太积极地使用显示硬件)。执行错误#378: DEVICE_REMOVAL_PROCESS_AT_FAULT

下面是正在讨论的代码。我省略了过滤器的代码,因为它使它能够很好地通过所有过滤器(我在调试器中遍历了它),并且只在它复制回CPU时抛出异常。下面的代码中的问题行是concurrency::copy(frame, begin(cpu_frame));

代码语言:javascript
复制
array<float_3, 2> convert_input(std::vector<float_3> &output, unsigned short *input, int n, int m) {
    int o = 0;

    for (int i = 0; i < n * m * 3; i += 3) {
        output[o] = float_3((float)input[i] / (float)MAXUINT16, (float)input[i + 1] / (float)MAXUINT16, (float)input[i + 2] / (float)MAXUINT16);
        o++;
    }

    return array<float_3, 2>(n, m, begin(output));
}

void _stdcall remove_gradient(unsigned short *input, float *output, int n, int m)
{
    std::vector<float_3> cpu_frame(n * m);

    array<float_3, 2> frame = convert_input(cpu_frame, input, n, m);

    GradientRemovalFilter *filter = new GradientRemovalFilter();

    try {
        filter->FilterFrame(frame);

        concurrency::copy(frame, begin(cpu_frame));
    }
    catch (accelerator_view_removed &ex) {
        std::cout << ex.what() << std::endl;
        std::cout << ex.get_view_removed_reason() << std::endl;
    }

    for (int i = 0; i < n * m; i ++) {
        output[(i * 3)] = cpu_frame[i].r;
        output[(i * 3) + 1] = cpu_frame[i].g;
        output[(i * 3) + 2] = cpu_frame[i].b;
    }
}

你知道哪里出了问题吗?如何预防?我的测试图像大约有10,000个像素,非常小,比我在现实中要做的要小得多,所以我不明白为什么要花足够长的时间才能让TDR启动,特别是当复杂的处理和复制到GPU的工作完成得很好时。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-04-25 05:07:40

上面的错误输出告诉了您发生了什么:您的着色器花了很长时间,驱动程序计算出GPU挂起。

这里的建议是:

  • 将处理分解为较小的块或简化计算操作。
  • D3D11_CREATE_DEVICE_DISABLE_GPU_TIMEOUT与DirectX 11.1+一起使用(参见这个职位)
  • 或者编辑注册表来扩展超时,这实际上只对开发有用。

编辑:问题最可能出现在filter->FilterFrame中,这是C++ AMP代码,它成为可能导致TDR的DirectCompute着色器。由于CPU/GPU同步/定时的差异,错误稍后返回的事实并不令人惊讶。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/29859631

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档