gpt4 book ai didi

c++ - 如何同时在 CPU 和 GPU 设备上运行任务?

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:35:08 25 4
gpt4 key购买 nike

我有这段代码,它是经过概要分析、优化和缓存高效的,因为我可能会以我的知识水平获得它。它在概念上像这样在 CPU 上运行:

#pragma omp parallel for schedule(dynamic)
for (int i = 0; i < numberOfTasks; ++i)
{
result[i] = RunTask(i); // result is some array where I store the result of RunTask.
}

恰好 RunTask() 本质上是一组线性代数运算,每次都在同一个非常大的数据集上重复运算,因此适合在 GPU 上运行。所以我想实现以下目标:

  1. 将一些任务卸载到 GPU
  2. 当 GPU 繁忙时,将其余任务交给 CPU 处理
  3. 对于 CPU 级别的操作,保留我的 super RunTask() 函数,而无需修改它以符合 restrict(amp)。我当然可以为 GPU 任务设计一个 restrict(amp) 兼容的 lambda。

最初我想做以下事情:

// assume we know exactly how much time the GPU/CPU needs per task, and this is the 
// most time-efficient combination:
int numberOfTasks = 1000;
int ampTasks = 800;

// RunTasksAMP(start,end) sends a restrict(amp) kernel to the GPU, and stores the result in the
// returned array_view on the GPU
Concurrency::array_view<ResulType, 1> concurrencyResult = RunTasksAMP(0,ampTasks);

// perform the rest of the tasks on the CPU while we wait
#pragma omp parallel for schedule(dynamic)
for (int i = ampTasks; i < numberOfTasks; ++i)
{
result[i] = RunTask(i); // this is a thread-safe
}

// do something to wait for the parallel_for_each in RunTasksAMP to finish.
concurrencyResult.synchronize();
//... now load the concurrencyResult array into the first elements of "result"

但我怀疑你能不能做这样的事情,因为

A call to parallel_for_each behaves as though it's synchronous

( http://msdn.microsoft.com/en-us/library/hh305254.aspx )

那么是否有可能实现我的 1-3 个请求,还是我必须放弃第 3 个请求?即便如此,我将如何实现它?

最佳答案

请参阅我对 will array_view.synchronize_asynch wait for parallel_for_each completion? 的回答解释为什么 parallel_for_each 可以被视为排队或调度操作而不是同步操作。这解释了为什么您的代码应该满足您的要求 1 和 2。它还应该满足要求 3,尽管您可能想考虑使用一个 restrict(cpu, amp) 函数,因为这会给您带来更少维护代码。

但是,您可能需要考虑您的方法对性能的一些影响。

首先,parallel_for_each 仅队列起作用,来自主机和 GPU 内存的数据拷贝使用主机资源(假设您的 GPU 是离散的和/或不支持直接复制)。如果您在主机上的工作耗尽了保持 GPU 工作所需的所有资源,那么您实际上可能会减慢 GPU 计算速度。

其次,对于许多数据并行且适合在 GPU 上运行的计算来说,它们的速度要快得多,以至于尝试在 CPU 上运行工作的额外开销不会导致整体加速。开销包括第一项(上文)和在主机上协调工作的额外开销(调度线程、合并结果等)。

最后,您上面的实现没有考虑在 GPU 和 CPU 上运行任务所花费的时间的任何可变性。它假定 800 个 AMP 任务将花费与 200 个 cpu 任务一样长的时间。这在某些硬件上可能是正确的,但在其他硬件上则不然。如果一组任务花费的时间比预期的要长,那么您的应用程序将阻塞并等待较慢的一组任务完成。您可以使用主/工作模式从队列中提取任务,直到没有更多可用任务为止,从而避免这种情况。这种方法意味着在最坏的情况下,您的应用程序将不得不等待最终任务完成,而不是任务 block 。使用主/工作方法还意味着无论 CPU/GPU 的相对性能如何,您的应用程序都将以相同的效率运行。

My book讨论了使用 master/worker(n-body)和并行队列(cartoonizer)跨多个 GPU 调度工作的示例。您可以从CodePlex 下载源代码。 .请注意,基于与 C++ AMP 产品团队的讨论,出于上述原因,它有意不涵盖 CPU 和 GPU 上的共享工作。

关于c++ - 如何同时在 CPU 和 GPU 设备上运行任务?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19800581/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com