怎么解决低的kernel并行率

  • 1 replies
  • 301 views
怎么解决低的kernel并行率
« 于: 五月 21, 2019, 11:50:21 am »
1.profiler分析提示低的kernel并行,如下所示,for循环里面红 蓝两部分的计算是独立进行的,怎么将这两部分就行并行运算?
2.试过流操作,但是并没有效果,发现流操作处理不了这种不需要在CPU/GPU间传输函数的情况,流操作的时间仅仅是将非流操作的时间相加
3.而且还有个问题,流操作是在<<<>>>中添加流参数,我这里有个cufft运算,直接调用库的,并不需要输入<<<>>>,所以如果想要进行流操作,应该怎么做?
4.因为数据量也挺大1024*1024的矩阵 ,运行时grid(8,128),block(128,8),这种如果想要红蓝并行运算是不是只能采取多GPU硬件?

srand((unsigned int)time(NULL));
   for (int ii = 0; ii < Num; ii++)
   {
      //二项分布的随机扰动
      generateRandom << <1, Z_Num >> > (rand(), d_dz);

      //根据泽尼克系数产生波面
      WAVE2 << <Grid1, Block1>> > (d_wave, d_tempwave, d_ZArray, d_Zer, d_dz, S, Z_Num);

      //正向扰动
      AmplitudeAdd << <Grid1, Block1 >> > (d_Data, d_Data0, d_wave, d_tempwave, S);
      Reconstruct11(d_Data0, d_Data00, S, plan, Grid1, Block1);//复振幅重建图像(含一次kernel运算和一次cufft)
      ComplexToFloat240 << <Grid1, Block1 >> > (d_Data00, d_Float00, S, SN);//求数据的绝对值的2.4次方
      Reduction1(d_Jp, d_partial00, d_Float00, N, Numblocks, Numthreads);//归约


      //负向扰动
      AmplitudeSub << <Grid1, Block1 >> > (d_Data, d_Data1, d_wave, d_tempwave, S);
      Reconstruct11(d_Data1, d_Data11, S, plan, Grid1, Block1);
      ComplexToFloat240 << <Grid1, Block1 >> > (d_Data11, d_Float11, S, SN);
      Reduction1(d_Jn, d_partial11, d_Float11, N, Numblocks, Numthreads);


      Mult0 << <1, Z_Num >> > (d_Zer, d_Jp, d_Jn, d_dz, gama, Z_Num);
   }

Re: 怎么解决低的kernel并行率
« 回复 #1 于: 五月 21, 2019, 01:00:46 pm »
1.profiler分析提示低的kernel并行,如下所示,for循环里面红 蓝两部分的计算是独立进行的,怎么将这两部分就行并行运算?
2.试过流操作,但是并没有效果,发现流操作处理不了这种不需要在CPU/GPU间传输函数的情况,流操作的时间仅仅是将非流操作的时间相加
3.而且还有个问题,流操作是在<<<>>>中添加流参数,我这里有个cufft运算,直接调用库的,并不需要输入<<<>>>,所以如果想要进行流操作,应该怎么做?
4.因为数据量也挺大1024*1024的矩阵 ,运行时grid(8,128),block(128,8),这种如果想要红蓝并行运算是不是只能采取多GPU硬件?

srand((unsigned int)time(NULL));
   for (int ii = 0; ii < Num; ii++)
   {
      //二项分布的随机扰动
      generateRandom << <1, Z_Num >> > (rand(), d_dz);

      //根据泽尼克系数产生波面
      WAVE2 << <Grid1, Block1>> > (d_wave, d_tempwave, d_ZArray, d_Zer, d_dz, S, Z_Num);

      //正向扰动
      AmplitudeAdd << <Grid1, Block1 >> > (d_Data, d_Data0, d_wave, d_tempwave, S);
      Reconstruct11(d_Data0, d_Data00, S, plan, Grid1, Block1);//复振幅重建图像(含一次kernel运算和一次cufft)
      ComplexToFloat240 << <Grid1, Block1 >> > (d_Data00, d_Float00, S, SN);//求数据的绝对值的2.4次方
      Reduction1(d_Jp, d_partial00, d_Float00, N, Numblocks, Numthreads);//归约


      //负向扰动
      AmplitudeSub << <Grid1, Block1 >> > (d_Data, d_Data1, d_wave, d_tempwave, S);
      Reconstruct11(d_Data1, d_Data11, S, plan, Grid1, Block1);
      ComplexToFloat240 << <Grid1, Block1 >> > (d_Data11, d_Float11, S, SN);
      Reduction1(d_Jn, d_partial11, d_Float11, N, Numblocks, Numthreads);


      Mult0 << <1, Z_Num >> > (d_Zer, d_Jp, d_Jn, d_dz, gama, Z_Num);
   }


很多时候,Visual Profiler的提示是没有道理的,可以忽略。不一定它怎么提示,你就必须怎么做。

例如当你不需要两个小kernel并行的时候,或者无法让它们并行的时候(例如受限于逻辑,或者kernel启动规模),则可以直接无视profiler的“low kernel concurrency"之类的提示的。

类似的还有low memcpy/kernel overlap之类的提示,很多人的很多代码并不需要计算和传输并行或者不能这样,也可以无视。