这样做可以是可以, 但是没有必要上2个context, 使用1个context, 里面2个设备即可.
对于这种实质上是一个整体的设备(APU或者Intel的带有核显的CPU), 因为实质的物理存储是一个芯片, 将两个设备放入同一个context, 可以共享一些东西. 最重要的是可能你的只读的一些数据, 例如可以被共享的一些buffer. 这样实现有可能共享他们, 提高性能.
其次, 只需要queue对应2个设备即可, 这样你不需要考虑后续的设备的存在, 只需要考虑queues间的关系即可. 例如在实质的应用中, 多个队列中的任务处理速度可能是不同的, 他们完全可以竞争性的从一个总的task pool中, 抢占性的获取任务(例如你有可以有24个任务, 12个队列, 这些队列从总的任务池中获取任务即可). 这样如果同时存在对于特性算法实现的速度快慢不同的设备, 例如你这种的1个CPU, 一个GPU, 完全可能CPU处理了1/3, 而GPU处理了2/3, 这样不需要静态的切分任务在2个设备间.
此外, 这还有个好处, 有12个任务, 不需要12个队列. 例如可以CPU和GPU上都只有3个队列, 任务总数为N(例如12), 每个队列里面都获取任务--判断任务池是否为空---不为空处理一个任务---处理完成后继续此逻辑循环. 这样可以实现动态的任务分配.
总之这样写正确是正确的, 但可以更优化一点. 普通的任务池可以简单的用个FIFO之类的数据结构, 单独上个线程产生任务, 然后3+3个OpenCL调度者从这里取任务. 轻松实现自动负载均衡.
实质的生活中的情景要复杂一些, 因为任务间还有依赖, 实质的生活要使用Graph这种数据结构. 但这里直接上个FIFO(例如CPU端的普通Queue<>之类的实现, 能有线程安全的Enqueue, Dequeue()之类的操作即可), 就可以实现全自动平衡负载了.
不妨试试看. 或者你也可以手工尝试找一个固定的平衡点, 在你的特定任务和机器上. 例如3:9? 4:8? 这种. 手工的需要你额外的工作量, 而且换个机器就没用了.
Regards,
屠戮人神.