C# 围绕GPULaunch循环或在内核中使用ALEA库循环

C# 围绕GPULaunch循环或在内核中使用ALEA库循环,c#,gpu,aleagpu,C#,Gpu,Aleagpu,我需要使用一个整数(0-99)作为参数,使用相同的数据运行我的GPU内核(ALEA库)100次。我试图在内核中实现这个循环,但得到了奇怪的结果。我必须将循环从内核中取出,围绕GPULaunch函数,如下所示: var lp = new LaunchParam(GridDim, BlockDim); for (int i= 0; i < 100; i++) { GPULaunch(TestKernel, lp, Data, i); } var lp=新启动参数(GridDim、Blo

我需要使用一个整数(0-99)作为参数,使用相同的数据运行我的GPU内核(ALEA库)100次。我试图在内核中实现这个循环,但得到了奇怪的结果。我必须将循环从内核中取出,围绕GPULaunch函数,如下所示:

var lp = new LaunchParam(GridDim, BlockDim);
for (int i= 0; i < 100; i++)
{
   GPULaunch(TestKernel, lp, Data, i);
}
var lp=新启动参数(GridDim、BlockDim);
对于(int i=0;i<100;i++)
{
GPULaunch(TestKernel,lp,Data,i);
}
代码的CPU版本经过高度优化,有效地使用了4个内核(%100)。根据合并内存访问原则重新组织内存中的数据后,我可以拥有%92的占用率和%96的全局负载效率。但是,GPU版本只比CPU版本快50%。我怀疑这样循环GPULaunch是否有效

如下图所示,我在NVIDIA Visual Profilier中没有看到重复的内存传输。一旦我将数据加载到GPU(在图中没有看到,但对我来说并不重要),我会得到一个短内存传输,输出100个循环,如右端所示。所以我的问题是:

  • 这种在循环中调用GPULaunch的方法是否具有相同数据的不可见内存传输
  • 如果有这样的开销,我需要在内核中有这个循环。我该怎么做呢。我尝试过,但结果不稳定,认为这种方法不适合GPU并行编程体系结构
  • 提前谢谢


    我又一次尝试在内核中实现这个循环,它成功了。我不知道这次有什么不同。下面是明显的代码(只是模板不是工作代码):

    公共类GPUModule:ILGPUModule
    {
    公共GPUModule(GPUModuleTarget目标):基本(目标)
    {
    }
    [内核]
    公共MyKernel(deviceptr数据)
    {
    var start=blockIdx.x*blockDim.x+threadIdx.x;
    int ind=threadIdx.x;
    
    对于(int i=0;像您这样的iLooks仍然在使用AleaGPU 2.x,最新的版本是AleaGPU 3.x,但API有所变化(www.AleaGPU.com)。此外,什么类型是
    HOIndex
    ,什么类型是
    Data
    ?我重新安装了Alea.IL.dll,所以现在它是3.0.0.0版,但根据Nuget信息,其他版本是最新版本。HOIndex是整数“i”事实上,我忘了更改它,我用I替换了它。数据表示两个输入数组和两个输出数组。这是一个简化的模板。无论如何,它不会影响循环。我再次尝试内核循环,这次它工作了,我不知道为什么。
    public class GPUModule : ILGPUModule
    {
    
      public GPUModule (GPUModuleTarget target) : base(target)
      {
      }
    
      [Kernel]
      Public MyKernel(deviceptr<int> Data)
      {
        var start = blockIdx.x * blockDim.x + threadIdx.x;
        int ind = threadIdx.x;
    
        for (int i=0;i<100;i++)
        {
          //Kernel Code here
        }
      }
    
      public void Dilimle_VerilerB(deviceptr<int> Data
      {
        ...
        var lp = new LaunchParam(GridDim, BlockDim);
        GPULaunch(TestKernel, lp, Data, HOIndex);
        ...
      }
    }