我在理解如何或是否可以在gpu和cpu之间共享工作负载方面遇到了一些问题。我有一个大型日志文件,我需要读取每一行,然后运行大约500万次操作(测试各种场景)。我目前的方法是读取几百行,将其添加到一个数组,然后将其发送到每个GPU,这是正常工作,但因为每行有这么多的工作,这么多行需要很长时间。我注意到,虽然这是在我的CPU核心基本上什么都不做。我正在使用EC2,所以我有2个四核Xeon& 2个特斯拉GPU,一个CPU核心读取文件(运行主程序),GPU正在完成工作,所以我想知道如何或者我该怎么做让其他7个核心参与到这个过程中?
我对如何设计程序以平衡GPU / CPU之间的任务感到困惑,因为他们都会在不同的时间完成作业,所以我不能同时将它们全部发送给他们。我考虑过建立一个队列(我是c的新手,所以不确定这是否可行)但是有没有办法知道GPU作业何时完成(因为我认为向Cuda发送作业是异步的)?我的内核非常类似于普通的c函数,因此将其转换为cpu使用并不是问题,只是平衡工作似乎是个问题。我再次通过'Cuda示例',但实际上找不到任何涉及这种平衡的东西。
任何建议都会很棒。
答案 0 :(得分:4)
我认为关键是创建一个多线程应用程序,遵循所有常见做法,并有两种类型的工作线程。一个可以与GPU一起工作,一个可以与CPU一起工作。所以基本上,你需要一个线程池和一个队列。
http://en.wikipedia.org/wiki/Thread_pool_pattern
队列可以非常简单。您可以拥有一个共享整数,该整数是日志文件中当前行的索引。当线程准备好检索更多工作时,它会锁定该索引,从日志文件中获取一定数量的行,从索引指定的行开始,然后按索引检索的行数增加索引,然后解锁
当一个工作线程完成了一个日志文件块时,它会将结果发送回主线程并获得另一个块(如果没有更多的线要处理,则退出)。
该应用程序启动GPU和CPU工作线程的某种组合,以利用所有可用的GPU和CPU核心。
您可能遇到的一个问题是,如果CPU繁忙,GPU的性能可能会受到影响,因为引入了新工作或处理GPU结果的轻微延迟。您可能需要尝试线程数及其亲和力。例如,您可能需要通过操纵线程关联来为每个GPU保留一个CPU核心。
答案 1 :(得分:1)
既然你逐行说可以在2个不同的流程中拆分工作 - 一个CPU + GPU进程 一个CPU进程利用剩余的7个核心
你可以用不同的偏移开始每个过程 - 比如第一个过程读取1-50,101-150等行,而第二个过程读取51-100,151-200等
这将避免您优化CPU-GPU交互的麻烦