C# 围绕GPULaunch循环或在内核中使用ALEA库循环
我需要使用一个整数(0-99)作为参数,使用相同的数据运行我的GPU内核(ALEA库)100次。我试图在内核中实现这个循环,但得到了奇怪的结果。我必须将循环从内核中取出,围绕GPULaunch函数,如下所示: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
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个循环,如右端所示。所以我的问题是:
我又一次尝试在内核中实现这个循环,它成功了。我不知道这次有什么不同。下面是明显的代码(只是模板不是工作代码):
公共类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);
...
}
}