我们有一个多GPU架构(在Windows上),其中可以指定'作业'(这也指定他们应该在哪个GPU上完成),然后在特定的GPU上执行。 目前,我们的方法是在框架的启动我们为每个GPU创建一个“工作线程”,然后等待作业被处理。具体而言,我们使用“GPUWorker”类从https://devtalk.nvidia.com/search/more/sitecommentsearch/GPUworker/好的策略多GPU处理与CPU线程,cuda上下文创建开销
它可以很好地,到目前为止,但有一些严重的性能相关的缺点:
在我们frameowrk,特定的GPU被锁定的全部时间即使GPU只在50%的工作时间内实际使用,也是“工作”的一部分。注意作业具有非常粗糙的粗糙度,例如'做光流计算',其可以采取例如50 - 100毫秒。
人们不能具体的“异步”的工作(例如一个aysnchronous主机设备拷贝),它不锁GPU
所以我现在想对这个问题“好”的策略。 我的想法如下:对于'已启动'的每个新作业,我创建一个新的'临时'CPU线程。 CPU线程然后设置将在其上完成工作的GPU的设备编号(通过'cudaSetDevice')。我想在这个时候(对我来说很简单,就是创建一个Cuda环境,在发布正确的设备之后,作业的'doWork'功能由CPU线程执行,取决于作业是同步的还是异步的,一个“加入”完成(等待CPU线程完成)或不
我现在有几个问题:
那是一个“好”的策略,或者是否有人知道的更好当然这应该是一个线程安全的策略
在我提出的策略中,典型的是什么新CPU线程创建的开销(以毫秒为单位)以及Cuda上下文的(隐藏)创建)?此外,如果例如Cuda上下文的创建是有意义的,有没有办法(例如使用cuda设备api和某种'上下文迁移')来减少这种开销?