请教:Cpp文件中有多线程调用cu文件的kernel函数只能串行执行吗?

  • 6 replies
  • 3077 views
请教论坛的[名词2],我的C++项目中要调用cu文件实现的函数功能fun,该函数是由一系列kernel函数实现的,且已经采用了流来实现。目前由于我需要在Cpp文件中开启3个线程,同时调用该函数fun,通过测试发现完成这3次调用的时间是单独调用一次函数的时间的3倍。这是说GPU不能由主机的多线程调用而并行执行这些相同的kernel函数吗?我目前用的RTX3090,显存是足够的。
如果我把这个函数改写成3个不同的名称,同时把核函数的名字也都改成写不同的名称,能够实现并行执行吗?
刚学习CUDA不久,如果说的不清楚或请见谅。

请教论坛的[名词2],我的C++项目中要调用cu文件实现的函数功能fun,该函数是由一系列kernel函数实现的,且已经采用了流来实现。目前由于我需要在Cpp文件中开启3个线程,同时调用该函数fun,通过测试发现完成这3次调用的时间是单独调用一次函数的时间的3倍。这是说GPU不能由主机的多线程调用而并行执行这些相同的kernel函数吗?我目前用的RTX3090,显存是足够的。
如果我把这个函数改写成3个不同的名称,同时把核函数的名字也都改成写不同的名称,能够实现并行执行吗?
刚学习CUDA不久,如果说的不清楚或请见谅。

在3个streams里面启动多个kernel,这些kernel能否并行的主要决定因素不在于它们的名字,而在于每个kernel所占用的资源。如果每个kernel每次的启动规模较小,就像自带的concurrentKernels例子那样,它们是可以并行的。

反过来,如果每个kernel的启动规模较大,可以充分压满你的卡,则最多只能在开头结尾的时候稍微并行一点点。

根据你的描述来看,应该属于后者。

是的,确实我的这些kernel的规模较大,那我怎么才能知道是不是调用一次就压满卡了呢?有什么方法可以监测吗?感觉3090的核心数量和显存都挺大的了。
或者,我还可以用什么别的方法实现同时并行执行这些kernel吗?
谢谢您的回答。

在3个streams里面启动多个kernel,这些kernel能否并行的主要决定因素不在于它们的名字,而在于每个kernel所占用的资源。如果每个kernel每次的启动规模较小,就像自带的concurrentKernels例子那样,它们是可以并行的。

反过来,如果每个kernel的启动规模较大,可以充分压满你的卡,则最多只能在开头结尾的时候稍微并行一点点。

根据你的描述来看,应该属于后者。


是的,确实我的这些kernel的规模较大,那我怎么才能知道是不是调用一次就压满卡了呢?有什么方法可以监测吗?感觉3090的核心数量和显存都挺大的了。
或者,我还可以用什么别的方法实现同时并行执行这些kernel吗?
谢谢您的回答。


是的,确实我的这些kernel的规模较大,那我怎么才能知道是不是调用一次就压满卡了呢?有什么方法可以监测吗?感觉3090的核心数量和显存都挺大的了。
或者,我还可以用什么别的方法实现同时并行执行这些kernel吗?
谢谢您的回答。

正常情况下(现在的人的用法),一次启动基本所有的卡都会压满,毕竟8.6的卡(你的3090例如),一个SM最多(最好情况),也不过只能上1536个线程/SM。你自己乘以自己的SM数量看看。现在动辄庞大的block数量卡已经不堪了。

可以从其他方面尝试突击,你可以考虑将你的计算和传输任务重叠,这样几乎是在不改动任何Kernel的代码实现的情况下,唯一能榨取的点了(当然,你可以上双卡)。

搜索nsight system/compute的字样可以给你更多信息。

正常情况下(现在的人的用法),一次启动基本所有的卡都会压满,毕竟8.6的卡(你的3090例如),一个SM最多(最好情况),也不过只能上1536个线程/SM。你自己乘以自己的SM数量看看。现在动辄庞大的block数量卡已经不堪了。

可以从其他方面尝试突击,你可以考虑将你的计算和传输任务重叠,这样几乎是在不改动任何Kernel的代码实现的情况下,唯一能榨取的点了(当然,你可以上双卡)。

搜索nsight system/compute的字样可以给你更多信息。

好的,谢谢!

是的,确实我的这些kernel的规模较大,那我怎么才能知道是不是调用一次就压满卡了呢?有什么方法可以监测吗?感觉3090的核心数量和显存都挺大的了。
或者,我还可以用什么别的方法实现同时并行执行这些kernel吗?
谢谢您的回答。

你可以用nsys或者nvvp看下实际执行时候的时间轴。如果2次kernel的启动,没有在轴上有时间上的重叠执行(前提是你的确使用了2个独立的流,并且流间没有event之类的依赖关系),那就是不能。

大部分人现在写的一次<<<>>>启动规模一般都会足压满卡,甚至会压满多次,此时一次性不能执行完所有的1个kernel的blocks/threads,一个kernel本身就需要多轮上到GPU上才能满足本次启动,更不用说有余力/剩余资源同时让给其他kernel启动中的blocks了。你可以看下ncu工具报告的waves(启动波次)情况。