在最坏的情况下,此示例是否在GPU全局内存中分配testCnt * xArray.Length存储?如何确保只将一个数组副本传输到设备? GpuManaged属性似乎可以达到此目的,但它并不能解决我们意外的内存消耗。
void Worker(int ix, byte[] array)
{
// process array - only read access
}
void Run()
{
var xArray = new byte[100];
var testCnt = 10;
Gpu.Default.For(0, testCnt, ix => Worker(ix, xArray));
}
修改
以更精确的形式提出的主要问题: 每个工作线程是否获得xArray的新副本,或者所有线程只有一个xArray副本?
答案 0 :(得分:2)
您的示例代码应在100 bytes
上的GPU
和100 bytes
内存中分配CPU
内存。
(.Net增加了一些开销,但我们可以忽略它)
由于您正在使用implicit memory
,因此需要分配一些资源来跟踪该内存(基本上它存在的位置:CPU/GPU
)。
现在......您可能会在CPU
方面看到更大的内存消耗假设。
由于内核编译在运行中,其原因是可能。
AleaGPU必须将您的IL
代码编译为LLVM
,LLVM
被送入Cuda编译器,后者又将其转换为PTX
。
第一次运行内核时会发生这种情况。
所有资源和非托管dll都被加载到内存中。
那是可能你所看到的。
testCnt
对分配的内存量没有影响。
修改* 强>
一个建议是以明确的方式使用内存。 它更快更有效:
private static void Run()
{
var input = Gpu.Default.AllocateDevice<byte>(100);
var deviceptr = input.Ptr;
Gpu.Default.For(0, input.Length, i => Worker(i, deviceptr));
Console.WriteLine(string.Join(", ", Gpu.CopyToHost(input)));
}
private static void Worker(int ix, deviceptr<byte> array)
{
array[ix] = 10;
}
答案 1 :(得分:1)
尝试使用显式内存:
static void Worker(int ix, byte[] array)
{
// you must write something back, note, I changed your Worker
// function to static!
array[ix] += 1uy;
}
void Run()
{
var gpu = Gpu.Default;
var hostArray = new byte[100];
// set your host array
var deviceArray = gpu.Allocate<byte>(100);
// deviceArray is of type byte[], but deviceArray.Length = 0,
assert deviceArray.Length == 0
assert Gpu.ArrayGetLength(deviceArray) == 100
Gpu.Copy(hostArray, deviceArray);
var testCnt = 10;
gpu.For(0, testCnt, ix => Worker(ix, deviceArray));
// you must copy memory back
Gpu.Copy(deviceArray, hostArray);
// check your result in hostArray
Gpu.Free(deviceArray);
}