Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
是C++;AMP库从F#中有用吗? 我正在试用C++中的C++ AMP库作为一种使用GPU并行工作的方式。然而,我得到的结果似乎并不直观 < C++ >中,我用一个函数将一个数组中的所有数字平方,使用AMP:< /P> 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(); } extern“C”\u declspec(dllexport)void\u stdcall square\u数组(双*arr,int n) { //在CPU上创建数据视图 数组_视图数据视图(n,&arr[0]); //在GPU上运行代码 每个(dataView.extent,[=](索引idx)的并行(amp) { dataView[idx]=dataView[idx]*dataView[idx]; }); //将数据从GPU复制到CPU dataView.synchronize(); }_F#_Task Parallel Library_Gpgpu_C++ Amp - Fatal编程技术网

是C++;AMP库从F#中有用吗? 我正在试用C++中的C++ AMP库作为一种使用GPU并行工作的方式。然而,我得到的结果似乎并不直观 < C++ >中,我用一个函数将一个数组中的所有数字平方,使用AMP:< /P> 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(); } extern“C”\u declspec(dllexport)void\u stdcall square\u数组(双*arr,int n) { //在CPU上创建数据视图 数组_视图数据视图(n,&arr[0]); //在GPU上运行代码 每个(dataView.extent,[=](索引idx)的并行(amp) { dataView[idx]=dataView[idx]*dataView[idx]; }); //将数据从GPU复制到CPU dataView.synchronize(); }

是C++;AMP库从F#中有用吗? 我正在试用C++中的C++ AMP库作为一种使用GPU并行工作的方式。然而,我得到的结果似乎并不直观 < C++ >中,我用一个函数将一个数组中的所有数字平方,使用AMP:< /P> 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(); } extern“C”\u declspec(dllexport)void\u stdcall square\u数组(双*arr,int n) { //在CPU上创建数据视图 数组_视图数据视图(n,&arr[0]); //在GPU上运行代码 每个(dataView.extent,[=](索引idx)的并行(amp) { dataView[idx]=dataView[idx]*dataView[idx]; }); //将数据从GPU复制到CPU dataView.synchronize(); },f#,task-parallel-library,gpgpu,c++-amp,F#,Task Parallel Library,Gpgpu,C++ Amp,(代码改编自伊戈尔·奥斯特罗夫斯基在MSDN上的代码。) 然后,我编写了以下F#来比较任务并行库(TPL)和AMP: //打印运行给定函数所需的时间 让时间f= let s=新秒表() s、 开始() f() s、 停止() printfn“已用时间:%d”s.ElapsedTicks CInterop模块= [] 外部无效方形数组(浮点[]数组,整数长度) let options=new parallel选项() 让尺寸=1000.0 设arr=[| 1.0..size] //将数组的给定索引

(代码改编自伊戈尔·奥斯特罗夫斯基在MSDN上的代码。)

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

//打印运行给定函数所需的时间
让时间f=
let s=新秒表()
s、 开始()
f()
s、 停止()
printfn“已用时间:%d”s.ElapsedTicks
CInterop模块=
[]
外部无效方形数组(浮点[]数组,整数长度)
let options=new parallel选项()
让尺寸=1000.0
设arr=[| 1.0..size]
//将数组的给定索引处的数字平方
让我=
do arr.[i]Parallel.For(0,arr.Length-1,选项,新操作(sq))|>忽略)
设arr2=[1.0..size]
//使用AMP对数组中的每个数字进行平方运算
时间(fun()->CInterop.square_数组(arr2,arr2.Length))
如果我将数组大小设置为一个很小的数字,如10,则需要TPL~22K个刻度和AMP~10K个刻度才能完成。这就是我所期望的。据我所知,GPU(因此是AMP)应该比TPL更适合这种工作被分解成非常小的部分的情况

但是,如果我将数组大小增加到1000,TPL现在需要~30K个刻度,AMP需要~70K个刻度。然后情况就变得更糟了。对于100万大小的阵列,AMP所需的时间几乎是TPL的1000倍

因为我希望GPU(即AMP)在这类任务上做得更好,所以我想知道我在这里遗漏了什么

我的显卡是GeForce 550 Ti,1GB,据我所知,不是一个懒散的人。我知道使用PInvoke调用AMP代码会有开销,但我希望这是一个固定的成本,在较大的数组大小上摊销。我相信数组是通过引用传递的(尽管我可能是错的),所以我不希望复制它会带来任何成本


谢谢大家的建议。

在GPU和CPU之间来回传输数据需要时间。您很可能在此处测量PCI Express总线带宽。对于GPU来说,1米浮子的平方是小菜一碟


使用
Stopwach
类来度量AMP的性能也不是一个好主意,因为GPU调用可以异步进行。在您的情况下,这是可以的,但是如果您只测量计算部分(每个计算部分的
并行\u
),这将不起作用。我想您可以使用D3D11性能计数器来实现这一点。

谢谢Stringer。我会在C++代码中添加更多的计时器来查看时间的准确度(感谢PARF计数器上的提示)。向所有人提出的问题:如果是带宽问题,是否有某种方法可以优化与GPU之间的数据传输?也就是说,如果游戏真的因为使用我的GPU而受到性能的影响,那么游戏就不会麻烦使用我的GPU,所以我假设他们做的事情是正确的,而我没有。@FSharpN00b这是一个相当大的问题。一种方法是将数据增量地移动到gpu,这样gpu就可以在等待剩余时间的同时完成一些工作data@mydogisbox是的,这是一种有效的隐藏数据传输的策略,它与compute重叠。谢谢mydogisbox和Ade。听起来,我应该坚持使用TPL,只担心在CPU耗尽后(不太可能)将数据异步移动到GPU,而不是先尝试到GPU。感谢大家的回复。您可能也对这个S3055感兴趣,它是一个动态CUDA,具有F#-用于.NET上GPU计算的新维度
// 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))