【问题标题】:Splitting up FOR loop for vectorizing so it runs quicker coding issue拆分 FOR 循环以进行矢量化,以便它运行更快的编码问题
【发布时间】:2015-06-25 09:42:21
【问题描述】:

我正在尝试矢量化并拆分 FOR 循环以使其运行得更快,但变量“aa_sig_combined_vect”在单元格 5569 之后开始返回除了零任何想法如何解决这个问题?请参阅下面的代码用户 krisdestruction 帮助我:

请注意,我使用的是带有 Octave 3.8.1 的 Ubuntu 14.04,这类似于 matlab,但遗憾的是缺少一些命令 parfor 命令在此版本的 octave 中没有完全实现。

t=rand(1,556790);
inner_freq=rand(8193,6);

N=100; % use N chunks
nn = int32( linspace(1, length(t)+1, N+1) );
aa_sig_combined_vect=zeros(size(t));
total_time_so_far=0;

D = diag(inner_freq(1:end-1,2));
A = inner_freq(1:end-1,1);
for ii=1:N
    ind = nn(ii):nn(ii+1)-1;
    tic;
    cosPara = 2 * pi * A * t(ind);
    toc;
    cosResult = cos( cosPara );
    sumParaA = D * cosResult;
    toc;
    sumParaB = repmat(inner_freq(1:end-1,3),[1 length(ind)]);
    toc;
    aa_sig_combined_vect(ind) = sum( sumParaA + sumParaB );
    toc;
    total_time_so_far=total_time_so_far+sum(toc)
    return;
end
fprintf('- Complete  test in %4.4fsec or %4.4fmins\n',total_time_so_far,total_time_so_far/60);

我试图提高速度的原始工作循环如下

clear all,
t=rand(1,556790);
inner_freq=rand(8193,6);

N=100; # use N chunks
nn = int32(linspace(1, length(t)+1, N+1))
aa_sig_combined=zeros(size(t));
total_time_so_far=0;

for ii=1:N
    tic;
    ind = nn(ii):nn(ii+1)-1;
    aa_sig_combined(ind) = sum(diag(inner_freq(1:end-1,2)) * cos(2 .* pi .* inner_freq(1:end-1,1) * t(ind)) .+ repmat(inner_freq(1:end-1,3),[1 length(ind)]));
    toc
    total_time_so_far=total_time_so_far+sum(toc)
end
fprintf('- Complete  test in %4.4fsec or %4.4fmins\n',total_time_so_far,total_time_so_far/60);

RMSERepmat = sqrt(mean((aa_sig_combined-aa_sig_combined_vect).^2)) %root men square error between two arrays lower is better

【问题讨论】:

    标签: arrays matlab for-loop octave vectorization


    【解决方案1】:

    嗯,原因很明显。 return 已添加到循环中,在第一次迭代后将其中断。我找到了这段代码的来源the answer,你可能已经注意到了:

    return 用于在第一次迭代后打破它,因为看起来其余的迭代都相似。

    更一般地说: 在循环中添加tic/toc 实际上会减慢速度。打印到屏幕上的任何内容都会减慢您的代码速度。在 MATLAB 和 Octave 中都有 inbuilt profiling 应该用于试图找出你的瓶颈是什么。

    此外,这一行在循环期间不会改变,因为inner_freq 不会改变,而ind 会改变,length(ind) 应该是相同的:

    repmat(inner_freq(1:end-1,3),[1 length(ind)]);
    

    因此,您也可以将其移出,并避免多次调用 repmat

    【讨论】:

    • 感谢您的帮助,我按照您所说的做了,当我移动 repmat(inner_freq(1:end-1,3),[1 length(ind)]);在 for 循环之外它运行了大约 7 次迭代,然后我得到一个错误。 “错误:test_vector_speed.m:运算符+:不一致的参数(op1 是 8192x5567,op2 是 8192x5568)错误:评估参数列表元素编号 1 错误:调用自:错误:/home/rt/Documents/octave/eq_research/main/transform /test_vector_speed.m 第 46 行第 28 列。”这表明 aa_sig_combined_vect(ind) = sum( sumParaA + sumParaB );
    • 那是因为您的样本数量不能均匀分配。您可以添加一些错误检查来捕获它,然后添加子索引,例如使用 repmat 一次制作 8192x5568,然后使用类似 sumParaB(:,1:length(ind))
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-24
    • 2013-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-02
    相关资源
    最近更新 更多