Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/16.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
Arrays 初始化非标准值的双数组的最快方法_Arrays_Matlab_Performance_Initialization_Gpgpu - Fatal编程技术网

Arrays 初始化非标准值的双数组的最快方法

Arrays 初始化非标准值的双数组的最快方法,arrays,matlab,performance,initialization,gpgpu,Arrays,Matlab,Performance,Initialization,Gpgpu,MATLAB提供了预分配/初始化数组的函数,这些函数使用诸如或之类的公共值。但是,如果我们希望数组具有一些任意双值,有多种方法可以实现,并且不清楚哪种方法更可取 这个问题并不是新问题——以前在和中讨论过。然而,经验表明,软件(特别是MATLAB及其执行引擎)和硬件随着时间的推移而变化,因此最好的方法可能在不同的系统上有所不同。不幸的是,前面提到的源代码没有提供基准测试代码,这可能是回答这个问题的最终(也是永恒的)方法 我正在寻找一个可以运行的基准测试,它可以告诉我在我的系统上使用的最快方法,考虑

MATLAB提供了预分配/初始化数组的函数,这些函数使用诸如或之类的公共值。但是,如果我们希望数组具有一些任意
,有多种方法可以实现,并且不清楚哪种方法更可取

这个问题并不是新问题——以前在和中讨论过。然而,经验表明,软件(特别是MATLAB及其执行引擎)和硬件随着时间的推移而变化,因此最好的方法可能在不同的系统上有所不同。不幸的是,前面提到的源代码没有提供基准测试代码,这可能是回答这个问题的最终(也是永恒的)方法

我正在寻找一个可以运行的基准测试,它可以告诉我在我的系统上使用的最快方法,考虑到我可能同时使用各种大小的“常规”双
数组和
gpuArray双
数组。

函数分配基准测试(arrSz)
如果nargin<1
arrSz=1000;
结束
%%公羊
t=[];
disp('--------------RAM中的分配-------------------')
t(end+1)=timeit(@()v1(arrSz),1);
t(end+1)=timeit(@()v2(arrSz),1);
t(end+1)=timeit(@()v3(arrSz),1);
t(end+1)=timeit(@()v4(arrSz),1);
t(end+1)=timeit(@()v5(arrSz),1);
t(end+1)=timeit(@()v6(arrSz),1);
t(end+1)=timeit(@()v7(arrSz),1);
t=1E3*t;%转换为毫秒
disp(t);disp(“”);
[~,I]=min(t);
disp(“结论:方法#“+I+”是CPU上最快的!”;disp(“”);
%%弗拉姆
如果gpuDeviceCount==0,则返回;结束
t=[];
disp('--------------在VRAM中的分配-------------------')
t(结束+1)=NaN;%不可能(?)在gpu上运行v1
t(end+1)=gputimeit(@()v2gpu(arrSz),1);
t(end+1)=gputimeit(@()v3gpu(arrSz),1);
t(end+1)=gputimeit(@()v4gpu(arrSz),1);
t(end+1)=gputimeit(@()v5gpu(arrSz),1);
t(end+1)=gputimeit(@()v6gpu(arrSz),1);
t(end+1)=gputimeit(@()v7gpu(arrSz),1);
t=1E3*t;%转换为毫秒
disp(t);disp(“”);
[~,I]=min(t);
disp(“结论:方法#“+I+”是GPU上最快的!”);
结束
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%RAM
功能输出=v1(M)
%在带有赋值的未定义矩阵上建立索引:
out(1:M,1:M)=pi;
结束
功能输出=v2(M)
%使用“one”函数对目标值进行索引:
标量=π;
out=标量(个(M));
结束
功能输出=v3(M)
%将“零”函数与加法一起使用:
out=零(M,M)+pi;
结束
功能输出=v4(M)
%使用“repmat”功能:
out=repmat(π,[M,M]);
结束
功能输出=v5(M)
%使用带乘法的“一”函数:
out=一(M)。*pi;
结束
功能输出=v6(M)
%带完全分配的默认初始化:
out=零(M);
out(:)=pi;
结束
功能输出=v7(M)
%使用“repelem”函数:
out=重复次数(pi,M,M);
结束
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%VRAM
功能输出=v2gpu(M)
标量=gpuArray(pi);
out=标量(gpuArray.ones(M));
结束
功能输出=v3gpu(M)
out=gpuArray.zeros(M,M)+gpuArray(pi);
结束
功能输出=v4gpu(M)
out=repmat(gpuArray(pi),[M,M]);
结束
功能输出=v5gpu(M)
out=gpuArray.ones(M)。*gpuArray(pi);
结束
功能输出=v6gpu(M)
%带完全分配的默认初始化:
out=gpuArray.zero(M);
out(:)=gpuArray(pi);
结束
功能输出=v7gpu(M)
%使用“repelem”函数:
out=重复次数(gpuArray(pi),M,M);
结束
运行上述操作(例如,输入
5000
)会产生以下结果:

--------------RAM中的分配---------------
110.4832  328.1685   48.7895   47.9652  108.8930   93.0481   47.9037
结论:方法#7是CPU上最快的!
---------------VRAM中的分配--------------
南37.0322 17.9096 14.2873 17.7377 16.1386 16.6330
结论:方法#4在GPU上速度最快!

。。。这告诉我们在任何情况下使用的最佳(或等效)方法。

我很确定我以前见过这种方法。你是不是抄袭了另一篇文章中的问题和答案?@Durkee绝对不是——我刚才自己写的。在与MATLAB相关的不同主题上有各种基准测试问题。你可能把它和别的东西混淆了。在发布之前,我确实努力找到了一个类似的问题,但我找不到完全相同的问题。当然,如果你能给我指出一篇非常相似的文章,我很乐意把我的答案移到那里(或者完全删除,如果它没有提供新的内容)。哦,对不起,我只记得这篇文章的CPU版本。不过,您可能需要考虑一个具有单精度的版本。在GPU上使用双精度通常不是一个好主意。@Durkee有链接吗?事实上,使用
单一
精度运行GPU计算有速度优势,但对于我来说,这与我的目的无关,因为我需要额外的精度。如果使用
single
精度,您是否怀疑基准会产生不同的结果(就最佳方法而言)?如果是这样的话,那么就更有理由使用基准测试代码。@Dev-iL内存分配对于single或double不会有什么不同(好吧,它将是x2)。不过,除非您使用的是特斯拉系列的GPU,否则在使用双倍运算的GPU中,计算速度将慢2倍以上,因为几乎所有的GPU处理器都是32位的。如果您有图像处理工具箱,则是另一种选择:
padarray(pi,[M,M]-1,pi,'post')
我建议这样做是为了让你的方法列表更加完整。@rahnema1我刚刚检查过,所以
padarray
调用
padarray\u algo
调用
MkConstary
,它只不过是
repmat
,这意味着它只是
v4
的一个较慢的版本(由于所有额外的步骤,如
padarray
)的输入验证。我已经在本地对其进行了基准测试,我的怀疑得到了证实-它的性能比
v4
稍差一点-与
v3
大致相同。因此,因为它只是