N0r*_*ert 1 matlab vectorization
在我的程序中,我需要计算总和:
.
我计算这个总和与新值2500倍C和z.
参数z可以是矢量.我编写了简单的for循环和矢量化版本代码,如下所示:
K = 200;
n_z = 40000;
C = ones(K,1); % an example, in real life the arey some coefficients (at next call will be new)
k = 0:K-1;
z = linspace(0, 2*pi, n_z); % at next call will be new
tic;
my_sum_for = zeros(1, K);
for i=1:n_z
my_sum_for(i) = C' * tan(k' * z(i));
end
toc; % Elapsed time is 1.820485 seconds.
tic;
my_sum = C' * tan(k' * z);
toc; % Elapsed time is 0.160924 seconds.
Run Code Online (Sandbox Code Playgroud)
矢量化版本更快,但还不够.是否有可能改进矢量化版本?
在Dominique Jacquel的回答之后我有了这个矢量化版本,它更快:
K = 200;
n_z = 40000;
C = ones(K,1)'; % an example, in real life they are some coefficients (at next call will be new)
k = (0:K-1)';
z = linspace(0, 2*pi, n_z); % at next call will be new
tic;
my_sum_for = zeros(1, K);
for i=1:n_z
my_sum_for(i) = C * tan(k * z(i));
end
toc; % Elapsed time is 1.521587 seconds.
tic;
my_sum = C * tan(k * z);
toc; % Elapsed time is 0.125468 seconds.
Run Code Online (Sandbox Code Playgroud)
是否有可能更多地改进矢量化版本(bsxfun,arrayfun或其他东西)?250秒的时间对我来说仍然很慢(占所有计算的75%).
我认为你非常接近这里的硬件限制.Matlab中的矩阵乘法是使用BLAS库完成的,这些库在性能方面已被证明难以击败.
AFAIK,切线功能具有实际专用硬件来计算其值.此外,Matlab会自动在多个内核上分配大型矩阵的触发函数,因此基本上没有什么可以改进的.
另外,如果我错了,请纠正我,但考虑到可能的数据开销和内存问题,我认为这个计算在GPU上实际上会更慢.
现在,如果你比较这些:
tic;
for ii = 1:10
my_sum = C * tan(k * z);
end
toc
tic;
for ii = 1:10
my_sum_notan = C * k * z;
end
toc
Run Code Online (Sandbox Code Playgroud)
你会发现所有的痛苦都来自切线函数,所以你最好关注它.正如你在这里看到的那样,如果你牺牲了一些准确性,基本上只能加速三角函数.
总之,你应该问自己这些问题:
你是否愿意放弃全双精度,或者说是"足够接近"的6位数?
你不能重新制定问题,以便事后计算切线吗?还是之前?或者,对于少得多的元素?在所述的问题中,这显然是不可能的,但我不知道完整的代码 - 可能有一些很好的触发身份可能适用于您的问题.
考虑到以上所有因素,优化这一点所需的工作量是否真的超过了更长的运行时间?与编写实现残缺但快速触发功能的自定义,难以移植的MEX功能相比,250秒听起来并不算太糟糕.
| 归档时间: |
|
| 查看次数: |
310 次 |
| 最近记录: |