GPU世界论坛 bbs.gpuworld.cn
Hi, 楼主, 你的想法很不错,也的确可以实现---从CUDA 3.2开始,也就是大约7年前,CUDA就已经支持多个CPU上的线程同时控制1块GPU了。但在实际使用中,往往需要考虑至少如下方面: (1)不能“用多个CPU核同时控制一个GPU”。因为正常的CUDA应用中,瓶颈往往在GPU自身的处理能力上(例如GPU本身的运算性能,访存性能,甚至是GPU到Host之间的数据传输能力上),而不在于用1个或者2个CPU核心控制GPU(例如发布kernel启动或者内存传输命令),还是用你的48个核心同时发布命令上。用简单的话说,往往一项工作,例如工地建设,往往进度受限于工地上工人的数量和能力,而不是受限于给这些工人下命令的领导者的数量。 (2)如果真的有特殊的应用场合,例如每次kernel启动非常小,却需要频繁的下发启动命令。此时看上去需要尽量提升CPU上的对GPU的命令下发能力,但这种场合已经从计算能力3.5的卡(Kepler架构),和CUDA 5.0开始,被一种叫动态并行的特性所取代。此特性允许GPU给GPU下达命令,启动kernel,而不是从CPU端。这种适合非常细小力度的并行处理应用,和不能及时从CPU端预先知道下发命令情况的处理----同时效果往往比你来自一堆CPU方的控制效果要好。 (3)唯一剩下的需要考虑的情况就是,需要将工作集在CPU和GPU之间划分,GPU处理一部分,CPU也处理一部分。想法看上去很美好,但实际上,往往你的GPU比CPU性能好的多,例如你的两张卡是GTX 1080 Ti(每个具有3584核),此时是否利用上剩下的CPU核心,往往不很重要。 需要指出的是,在一个具有48核的CPU的工作站上,和常见的对应这个级别的设备的GPU卡,稍微对GPU端的调度不及时(例如你的CPU核心用来执行CPU上的处理线程去了),所造成的性能损失,一般总是要大于你得到的来自CPU核心上的算力带来的性能提升,所以虽然你总是可以直接上多个CPU线程(例如通过pthread_create出来的), 但无论是调度(见1,2条)还是CPU直接干活(见3条),总是不建议的。 如果你真要这样做,请注意 (1)最多建议使用46个核心直接干活,剩下2个核心上的线程专心用于调度GPU。 (2)建议使用动态的任务的队列(或者图--如果任务之间有依赖关系的话),而不是静态的在CPU和GPU间的一定比例的任务切分, 以避免耽误GPU上的性能发挥。 (3)如果这个级别的GPU能从这点CPU算力上得到了显著的整体性能提升,请立刻检查你的GPU上的实现---这往往代表你的GPU代码实现的非常糟糕。