【问题标题】:Optimizing the value N to split arrays up for vectorizing an array so it runs the quickest优化值 N 以拆分数组以对数组进行矢量化,使其运行速度最快
【发布时间】:2015-06-24 15:30:11
【问题描述】:

我正在尝试优化值 N 以拆分数组以对数组进行矢量化,使其在不同机器上运行得最快。我下面有一些测试代码

#example use random values
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);

在运行 ubuntu 的 16gig i7 机器上 N=100 时,这需要 162.7963 秒或 2.7133 分钟才能完成

有没有办法找出 N 应该是什么值才能让它在不同的机器上以最快的速度运行?

PS:我在 16gig i7 ubuntu 14.04 上运行 Octave 3.8.1,但它也可以在 1 gig raspberry pi 2 上运行。

【问题讨论】:

  • 如果您非常关心性能,我会用 Fortran 或 C 编写循环,然后将其并行化(可能使用 OpenMP)。您也可以尝试在主循环之外预先计算一些东西,例如 length(ind) 或 inner_freq(1:end-1,1)。
  • OP 如果正确,你能接受我的回答吗?
  • @krisdestruction 我很乐意,但您的代码似乎不起作用......我在您的答案下的部分中包含了错误。我在网上多个地方和octave-online.net 一起尝试过,错误和'A'一起出现错误:运算符*:不符合要求的参数(op1 是 8192x8192,op2 是 1x5568)

标签: arrays matlab math octave mathematical-optimization


【解决方案1】:

这是我用来计时每个参数的Matlab测试脚本。 return 用于在第一次迭代后打破它,因为看起来其余的迭代都相似。

%example use random values
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));

D = diag(inner_freq(1:end-1,2));
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(ind) = sum( sumParaA + sumParaB );
    toc;
    return;
end

输出如下所示。请注意,我的电脑速度很慢。

Elapsed time is 0.156621 seconds.
Elapsed time is 17.384735 seconds.
Elapsed time is 17.922553 seconds.
Elapsed time is 18.452994 seconds.

如您所见,cos 操作需要很长时间。您在 8192x5568 矩阵(45,613,056 个元素)上运行 cos,这需要很长时间。

如果您希望提高性能,请使用parfor,因为每次迭代都是独立的。假设您有 100 个内核来运行 100 次迭代,您的脚本将在 17 秒 + parfor 开销内完成。

cos 计算中,您可能想了解是否存在另一种方法来计算一个值的 cos 比 stock 方法更快、更并行。

另一个小的优化是这一行。它确保不会在循环内调用 diag 函数,因为对角矩阵是常数。您不希望每次都生成 8192x8192 对角矩阵!我只是将它存储在循环之外,它也提供了一点性能提升。

D = diag(inner_freq(1:end-1,2));

请注意,我没有使用 Matlab 配置文件,因为它不适合我,但您将来应该使用它来编写更多功能化的代码。

【讨论】:

  • 我不断收到错误,其中未定义“A”并且错误:运算符 *:不符合要求的参数(op1 为 8192x8192,op2 为 1x5568)错误:调用自:错误:/home/rt/文档/octave/eq_research/main/transform/test_loop_speed.m 第 18 行第 14 列
  • 另外我使用的是 Octave 3.8.1,它还没有完全支持 parfor stackoverflow.com/questions/24970519/…
猜你喜欢
  • 2014-07-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-19
  • 1970-01-01
相关资源
最近更新 更多