Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/13.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 使用arrayfun在Matlab中快速生成for循环?_Arrays_Matlab_Parallel Processing - Fatal编程技术网

Arrays 使用arrayfun在Matlab中快速生成for循环?

Arrays 使用arrayfun在Matlab中快速生成for循环?,arrays,matlab,parallel-processing,Arrays,Matlab,Parallel Processing,目前,我有以下代码部分: for i = 2:N-1 res(i) = k(i)/m(i)*x(i-1) -(c(i)+c(i+1))/m(i)*x(N+i) +e(i+1)/m(i)*x(i+1); end 其中,变量k、m、c和e是大小为N的向量,x是大小为2*N的向量。有没有办法使用类似arrayfun的东西更快地实现这一点!?我无法理解这一点:(我特别希望以后在GPU上运行会更快,因此,arrayfun也会很有帮助,因为matlab不支持循环的并行化,我不想买夹克包。。。 非常感谢

目前,我有以下代码部分:

for i = 2:N-1
  res(i) = k(i)/m(i)*x(i-1) -(c(i)+c(i+1))/m(i)*x(N+i) +e(i+1)/m(i)*x(i+1);
end
其中,变量k、m、c和e是大小为N的向量,x是大小为2*N的向量。有没有办法使用类似arrayfun的东西更快地实现这一点!?我无法理解这一点:(我特别希望以后在GPU上运行会更快,因此,arrayfun也会很有帮助,因为matlab不支持循环的并行化,我不想买夹克包。。。
非常感谢!

首先,MATLAB确实支持并行for loops via。但是,这不太可能加快这种计算,因为与您正在读取和写入的数据量相比,计算量很小


为GPUArray“”重新构造内容的步骤,您需要使循环体中的所有数组引用都引用循环,并使循环在整个范围内运行。您应该能够通过偏移一些数组并使用伪值填充来实现这一点。例如,您可以使用
NaN
预先填充所有数组,并替换
x(i-1)
使用一个新变量
x_1=[x(2:N)NaN]

您不必使用arrayfun。如果使用一些智能索引:

    clear all

    N=20;
    k=rand(N,1);
    m=rand(N,1);
    c=rand(N,1);
    e=rand(N,1);
    x=rand(2*N,1);

    % for-based implementation
    %Watch out, you are not filling the first element of forres!
    forres=zeros(N-1,1); %Initialize array first to gain some speed.
    for i = 2:N-1
      forres(i) = k(i)/m(i)*x(i-1) -(c(i)+c(i+1))/m(i)*x(N+i) +e(i+1)/m(i)*x(i+1);
    end

    %vectorized implementation
    parres=k(2:N-1)./m(2:N-1).*x(1:N-2) -(c(2:N-1)+c(3:N))./m(2:N-1).*x(N+2:2*N-1) +e(3:N)./m(2:N-1).*x(3:N);

    %compare results; strip the first element from forres
    difference=forres(2:end)-parres %#ok<NOPTS>
全部清除
N=20;
k=兰特(N,1);
m=兰特(N,1);
c=兰特(N,1);
e=兰特(N,1);
x=兰特(2*N,1);
%基于对象的实现
%小心,你不是在填充forres的第一个元素!
forres=0(N-1,1);%首先初始化数组以获得一些速度。
对于i=2:N-1
forres(i)=k(i)/m(i)*x(i-1)-(c(i)+c(i+1))/m(i)*x(N+i)+e(i+1)/m(i)*x(i+1);
结束
%矢量化实现
parres=k(2:N-1)。/m(2:N-1)。*x(1:N-2)-(c(2:N-1)+c(3:N))/m(2:N-1)。*x(N+2:2*N-1)+e(3:N)。/m(2:N-1)。*x(3:N);
%比较结果;从forres中剥离第一个元素
差异=力量(2:结束)-招架%#确定

我假设一个
(x(I)-x(I-1))^3
到达
(x(2:N-1)-x(1:N-2))。^3
?是的,你得到了。策略是用for循环中的索引范围替换运行索引
I
。即对于
1:N
I
变为
1:N
I+1
变为
1+1“把戏"基本上都是使用
arrayfun
所需的。在GPU上使用
arrayfun
通常比一系列矢量化操作快得多。好吧,我想试试:但我在这里看到的问题是,当创建这么多“虚拟”变量时,我可能很快就会耗尽内存,而且,复制到GPU的速度会更快对所有不同变量的内存访问可能会非常慢!你是对的,你可能会遇到问题。不幸的是,arrayfun在它允许的范围内非常不灵活。如果你真的想要最高的速度,你可以编写少量的CUDA代码,并使用MATLAB中的parallel.gpu.CUDAKernel来执行它。是的,谢谢,我已经考虑过这一点,但只是想要一个“快速”的解决方案以及user599884的建议,帮助我创建了这样一个快速的解决方案,使for循环更快。你认为CUDA编写的代码真的会比GPU上运行的user599884解决方案更快吗?只需简单地将
x=gpuArray(x),k=gpuArray(k)
等等。是的,在GPU上,arrayfun或手工编写的内核通常比矢量化的代码要好。忽略索引偏移量并使用arrayfun来查看速度有多快,您可以粗略估计速度有多快。Edric,您认为完全像CUDA mex文件那样做也值得吗(比如将数据复制到GPU等)或者一个PTX内核就足够了吗?!我想知道这两个变体之间是否会有很大的区别。