如何在CPU

时间:2018-01-19 02:57:17

标签: cuda

我的工作使用4个流,我希望它们可以同时运行。代码是这样的:

for (int i=0; i<N; i++)   //batch numbers
{
    for (int j=0; j<4; j++)
       myCudaCode(stream[j]);    // working codes using the specified stream
}

但是,从nvvp profiler我看到流实际上并没有同时运行,因为CPU完全被内核启动占用。我没有使用任何cudaDeviceSynchronize。您可以从以下链接中看到该图。

enter image description here

据我所知,GPU上的所有内核都非常小,与CPU上的内核启动时间相当。但到目前为止,我们并不打算改变它们。从上图中,我看到CPU上的大多数内核启动大约需要5~10 us,这被认为是正常的。一批的整个处理时间约为0.4毫秒(如灰色所示)

优化代码的直观思维是使用多线程来并行化CPU上的CUDA内核启动。以下是我使用openMP所做的事情:

for (int i=0; i<N; i++)
{
    #pragma omp parallel num_threads(4)
       myCudaCode(stream[omp_get_thread_num()]);
}

现在nvvp探查器显示如下:

enter image description here

这四个流似乎同时运行。但是,对于每个CPU线程,CUDA内核的启动不再像以前那样紧凑,而且还会显着拉伸(通常为20~30 us)。一次批处理所需的时间(以灰色显示)现在大约为0.5ms,甚至比单线程情况更长。

我也试过pthread方法。它显示了类似的问题。

所以我想问一个有效的方法来平衡CPU上的内核启动。理想情况下,预计时间会减少四分之一。

我非常确定每个内核都足够小,远离完整的GPU计算资源。我正在使用Linux,i7 8核CPU和GTX 1070 GPU。

更新:根据我的实验,似乎使用多CPU线程根本不会减少总内核启动时间。假设用于处理N个流的单线程代码需要时间T,那么使用openMP和用于处理N个流的N线程代码(单线程用于单线程)也将近似需要时间T.如图所示,即使流现在看似并发,但每个内核启动延迟也变得很重要。有趣的是,总时间(对于一批或N个流)因此保持大致不变。

1 个答案:

答案 0 :(得分:-1)

我认为你需要创建多个流。如果您使用cuda 7.0 +,请检查每线程默认流。

https://devblogs.nvidia.com/gpu-pro-tip-cuda-7-streams-simplify-concurrency/

查看上面的链接以获取详细示例。