【问题标题】:Clueless on how to execute big tasks on C++ AMP对如何在 C++ AMP 上执行大任务一无所知
【发布时间】:2013-10-15 14:28:04
【问题描述】:

我的任务是查看我开发的算法是否可以在 GPU 而非 CPU 上运行得更快。我是加速器计算的新手,我得到了一本我已经彻底阅读过的书“C++ AMP”,我认为我对它的理解相当好(我过去用 C 和 C++ 编写过代码,但现在主要是 C#)。

但是,当进入实际应用程序时,我似乎只是不明白。所以,如果可以的话,请帮助我。

假设我有一个任务来计算一些复杂的函数,该函数需要一个巨大的矩阵输入(如 50000 x 50000)和一些其他数据并输出相同大小的矩阵。整个矩阵的总计算需要几个小时。

在 CPU 上,我只是将任务分成几部分(部分数量大约为 100 左右)并使用 Parralel.For 或只是我自己编写的一个简单的任务管理循环来执行它们。基本上,保持几个线程运行(线程数 = 内核数),当线程完成时开始新的部分,直到所有部分都完成。而且效果很好!

但是,在 GPU 上,我不能使用相同的方法,这不仅是因为内存限制(没关系,可以分成几个部分),而且因为如果某些东西运行超过 2 秒,它就会被认为是“超时” GPU被重置!因此,我必须确保我的计算的每个部分运行时间少于 2 秒。

但这并不是每个任务(例如,将一个小时的工作分成 60 个任务,每个任务 1 秒),这很容易,这就是每组任务,因为无论我选择哪种队列模式(立即或自动) ,如果我(通过 parralel_for_each)运行任何总耗时超过 2 秒的东西,GPU 将被重置。

不仅如此,如果我的 CPU 程序占用了所有 CPU 资源,只要它保持较低的优先级,UI 就会保持交互 - 系统是响应式的,但是,当在 GPU 上执行代码时,屏幕似乎被冻结,直到执行完毕!

那么,我该怎么办?在本书的演示(N-Body 问题)中,它表明它的效率应该是 100 倍(多核计算给出 2 gflops,或者 w/e 的 flops 数量,而 amp 给出 200 gflops),但是在实际应用中,我只是不知道该怎么做!

我是否必须将我的大任务划分为数十亿个部分,例如,划分为每个需要 10 毫秒执行的部分,并在 parralel_for_each 中一次运行 100 个?

或者我只是做错了,我没有得到更好的解决方案?

请帮忙!

【问题讨论】:

  • 不,很遗憾,这不是我想要的,我不需要增加超时时间,因为这会使用户在整个操作中显示冻结,这显然是不可取的。跨度>
  • 肯定显示冻结是一个单独的问题,您应该始终在与 GUI 线程分开的线程上执行长时间运行的任务,以便 UI 可以保持响应。

标签: c++ parallel-processing gpu gpgpu c++-amp


【解决方案1】:

TDR(您看到的 2 秒超时)是使用在渲染显示和执行计算工作之间共享的资源的现实。操作系统通过强制超时来保护您的应用程序免于完全锁定显示。这也会影响尝试渲染到屏幕的应用程序。将您的 AMP 代码移至单独的 CPU 线程将无济于事,这将释放 CPU 上的 UI 线程,但仍会阻止 GPU 上的渲染。

当您在低功耗系统上将 N 设置为非常大时,您实际上可以在 n 体示例中看到这种行为。 N的最大值实际上在应用程序中是有限的,以防止您在典型场景中遇到这些类型的问题。

你实际上是在正确的轨道上。如果您想达到特定的帧速率,您确实需要将您的工作分成适合低于 2s 的块或更小的块。您还应该考虑您的工作是如何排队的。请记住,所有 AMP 工作都是排队的,在自动模式下,您无法控制它何时运行。使用即时模式可以更好地控制命令的批处理方式。

注意:TDR 在专用计算 GPU 硬件(如 Tesla)上不是问题,如果底层 GPU 支持,Windows 8 在处理 TDR 超时限制时提供更大的灵活性。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-02-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多