在cuda中并行执行内核

时间:2015-07-09 19:05:53

标签: cuda parallel-processing nvidia

假设我有三个全局数组已经使用cudaMemcpy复制到gpu中但c中的这些gloabl数组尚未使用cudaHostAlloc分配,以便分配内存为页面锁定而不是简单的gloabl分配。

int a[100],b [100],c[100];
cudaMemcpy(d_a,a,100*sizeof(int),cudaMemcpyHostToDevice);
cudaMemcpy(d_b,b,100*sizeof(int),cudaMemcpyHostToDevice);
cudaMemcpy(d_c,c,100*sizeof(int),cudaMemcpyHostToDevice);

现在我有10个内核在单独的流中启动,以便同时运行,其中一些使用在gpu中复制的全局数组。 现在这些内核正在运行1000次迭代。 他们不必在迭代期间将任何东西复制回主机。

但问题是他们并没有并行执行,而是采用串行方式。

  cudaStream_t stream[3];

   for(int i=0;i<3;i++)cudaStreamCreate (&stream[i]);

   for(int i=0;i<100;i++){
       kernel1<<<blocks,threads,0,stream[0]>>>(d_a,d_b);
       kernel2<<<blocks,threads,0,strea[1]>>(d_b,d_c);
      kernal3<<<blocks,threads,0,stream[2]>>>(d_c,d_a);
    cudaDeviceSynchronize();
  }

我不明白为什么?

1 个答案:

答案 0 :(得分:4)

以这种方式发布的内核:

   for(int i=0;i<100;i++){
    kernel1<<<blocks,threads>>>(d_a,d_b);
    kernel2<<<blocks,threads>>>(d_b,d_c);
    kernal3<<<blocks,threads>>>(d_c,d_a);
    cudaDeviceSynchronize();
  }

将始终以串行方式运行。为了让内核同时运行,必须将它们发布到separate CUDA streams。还有其他要求。阅读documentation

你需要创建一些CUDA流,然后像这样启动你的内核:

   cudaStream_t stream1, stream2, stream3;
   cudaStreamCreate(&stream1); cudaStreamCreate(&stream2); cudaStreamCreate(&stream3);

   for(int i=0;i<100;i++){
    kernel1<<<blocks,threads,0,stream1>>>(d_a,d_b);
    kernel2<<<blocks,threads,0,stream2>>>(d_b,d_c);
    kernal3<<<blocks,threads,0,stream3>>>(d_c,d_a);
    cudaDeviceSynchronize();
  }

实际上目击并发内核执行通常还需要资源利用率有限的内核。如果给定的内核将“填充”机器,由于大量的块,每个块的线程,或共享内存使用,或其他一些资源使用,那么你实际上不会看到并发;机器里没有剩余空间。

您可能还想查看一些CUDA示例代码,例如simpleStreamsconcurrentKernels