是否可以在 GPU 和 CPU 之间拆分 Cuda 作业?
Posted
技术标签:
【中文标题】是否可以在 GPU 和 CPU 之间拆分 Cuda 作业?【英文标题】:Is it possible to split Cuda jobs between GPU & CPU? 【发布时间】:2012-06-07 11:58:54 【问题描述】:我在理解如何或是否可以在 gpu 和 cpu 之间分担工作负载时遇到了一些问题。我有一个大的日志文件,我需要读取每一行然后运行大约 500 万次操作(测试各种场景)。我目前的方法是读取几百行,将其添加到数组中,然后将其发送到每个 GPU,这工作正常,但因为每行工作量很大,而且行数很多,所以需要很长时间。我注意到,虽然这正在发生,但我的 CPU 内核基本上什么都不做。我正在使用 EC2,所以我有 2 个四核 Xeon 和 2 个 Tesla GPU,一个 cpu 核心读取文件(运行主程序)并且 GPU 完成工作,所以我想知道如何或可以做些什么来参与其他 7 个核心进入进程?
我有点困惑如何设计一个程序来平衡 GPU/CPU 之间的任务,因为它们都会在不同的时间完成工作,所以我不能同时将它发送给他们。我考虑过设置一个队列(我是 c 新手,所以不确定这是否可能)但是有没有办法知道 GPU 作业何时完成(因为我认为向 Cuda 发送作业是异步的)? I 内核与普通的 c 函数非常相似,因此将其转换为 cpu 使用不是问题,只是平衡工作似乎是问题。我再次浏览了“Cuda by example”,但实际上找不到任何涉及这种平衡的东西。
任何建议都会很棒。
【问题讨论】:
【参考方案1】:我认为关键是创建一个多线程应用程序,遵循所有常见做法,并拥有两种类型的工作线程。一种适用于 GPU,另一种适用于 CPU。所以基本上,你需要一个线程池和一个队列。
http://en.wikipedia.org/wiki/Thread_pool_pattern
队列可以很简单。您可以拥有一个共享整数,它是日志文件中当前行的索引。当一个线程准备好检索更多工作时,它会锁定该索引,从日志文件中获取一些行数,从索引指定的行开始,然后将索引增加它检索到的行数,然后解锁.
当工作线程处理完日志文件的一个块时,它会将其结果发送回主线程并获取另一个块(如果没有更多行要处理,则退出)。
应用启动 GPU 和 CPU 工作线程的某种组合,以利用所有可用的 GPU 和 CPU 内核。
您可能会遇到的一个问题是,如果 CPU 很忙,GPU 的性能可能会受到影响,因为在提交新工作或来自 GPU 的处理结果时会出现轻微延迟。您可能需要试验线程数及其亲和性。例如,您可能需要通过操纵线程关联性为每个 GPU 保留一个 CPU 内核。
【讨论】:
【参考方案2】:既然您说逐行可能是您可以将作业拆分为 2 个不同的流程 - 一个 CPU + GPU 进程 一个 CPU 进程使用了剩余的 7 个内核
您可以使用不同的偏移量启动每个进程 - 例如第一个进程读取 1-50、101-150 等行,而第二个进程读取 51-100、151-200 等行
这将避免您为优化 CPU-GPU 交互而头疼的问题
【讨论】:
以上是关于是否可以在 GPU 和 CPU 之间拆分 Cuda 作业?的主要内容,如果未能解决你的问题,请参考以下文章