C#AMP库是否适用于F#?

FSh*_*00b 5 f# gpgpu task-parallel-library c++-amp

我正在试验F#中的C++ AMP库,作为使用GPU并行工作的一种方式.但是,我得到的结果似乎并不直观.

在C++中,我创建了一个带有一个函数的库,它使用AMP对数组中的所有数字进行平方:

extern "C" __declspec ( dllexport ) void _stdcall square_array(double* arr, int n)
{
// Create a view over the data on the CPU
    array_view<double,1> dataView(n, &arr[0]);

// Run code on the GPU
    parallel_for_each(dataView.extent, [=] (index<1> idx) restrict(amp)
    {
        dataView[idx] = dataView[idx] * dataView[idx];
    });

// Copy data from GPU to CPU
    dataView.synchronize();
}
Run Code Online (Sandbox Code Playgroud)

(代码改编自Igor Ostrovsky 在MSDN上的博客.)

然后我编写了以下F#来比较任务并行库(TPL)和AMP:

// Print the time needed to run the given function
let time f =
    let s = new Stopwatch()
    s.Start()
    f ()
    s.Stop()
    printfn "elapsed: %d" s.ElapsedTicks

module CInterop =
    [<DllImport("CPlus", CallingConvention = CallingConvention.StdCall)>]
    extern void square_array(float[] array, int length)

let options = new ParallelOptions()
let size = 1000.0
let arr = [|1.0 .. size|]
// Square the number at the given index of the array
let sq i =
    do arr.[i] <- arr.[i] * arr.[i]
    ()
// Square every number in the array using TPL
time (fun() -> Parallel.For(0, arr.Length - 1, options, new Action<int>(sq)) |> ignore)

let arr2 = [|1.0 .. size|]
// Square every number in the array using AMP
time (fun() -> CInterop.square_array(arr2, arr2.Length))
Run Code Online (Sandbox Code Playgroud)

如果我将数组大小设置为像10这样的普通数字,则需要TPL~22K标记才能完成,AMP~10K标记.这就是我的期望.据我了解,GPU(因此AMP)应该更适合这种情况,其中工作分为非常小的部分,而不是TPL.

但是,如果我将数组大小增加到1000,则TPL现在需要大约30K的滴答,AMP需要大约70K的小时.它从那里变得更糟.对于大小为100万的阵列,AMP的使用时间是TPL的近1000倍.

由于我期望GPU(即AMP)在这种任务中更好,我想知道我在这里缺少什么.

我的显卡是一块1GB的GeForce 550 Ti,据我所知,这并不算懒散.我知道使用PInvoke调用AMP代码会产生开销,但我希望这是一个在更大的数组大小上摊销的固定成本.我相信数组是通过引用传递的(虽然我可能是错的),所以我不希望任何与复制相关的成本.

感谢大家的建议.

Str*_*ger 7

在GPU和CPU之间来回传输数据需要时间.您最有可能在此测量PCI Express总线带宽.平移1M的浮子是GPU的一块蛋糕.

使用Stopwach该类来测量AMP的性能也不是一个好主意,因为GPU调用可以异步发生.在你的情况下它是好的,但如果你只测量计算部分(parallel_for_each),这将无法正常工作.我认为你可以使用D3D11性能计数器.

  • @mydogisbox是的,这是一种有效的策略,可以通过将数据与计算重叠来隐藏数据传输. (2认同)