GPU全局内存计算

时间:2017-10-03 16:31:29

标签: c# aleagpu

在最坏的情况下,此示例是否在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副本?

2 个答案:

答案 0 :(得分:2)

您的示例代码应在100 bytes上的GPU100 bytes内存中分配CPU内存。 (.Net增加了一些开销,但我们可以忽略它)

由于您正在使用implicit memory,因此需要分配一些资源来跟踪该内存(基本上它存在的位置:CPU/GPU)。

现在......您可能会在CPU方面看到更大的内存消耗假设

由于内核编译在运行中,其原因是可能。 AleaGPU必须将您的IL代码编译为LLVMLLVM被送入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);
}