2

我很难掌握如何计算 FLOP。前一刻我觉得我明白了,下一刻我觉得毫无意义。一些帮助解释这一点将不胜感激。我查看了有关该主题的所有其他帖子,但没有一个完全用我熟悉的编程语言解释(我知道一些 MATLAB 和 FORTRAN)。

这是我的一本书中的一个示例,说明了我正在尝试做的事情。

对于下面的一段代码,触发器的总数可以写成(n*(n-1)/2)+(n*(n+1)/2)相当于n^2 + O(n).

[m,n]=size(A)
nb=n+1;
Aug=[A b];
x=zeros(n,1);
x(n)=Aug(n,nb)/Aug(n,n);
for i=n-1:-1:1
    x(i) = (Aug(i,nb)-Aug(i,i+1:n)*x(i+1:n))/Aug(i,i);
end

我正在尝试应用上述相同的原理来查找 FLOP 的总数作为n以下代码(MATLAB)中方程数量的函数。

% e = subdiagonal vector
% f = diagonal vector
% g = superdiagonal vector
% r = right hand side vector
% x = solution vector

n=length(f);

% forward elimination
for k = 2:n
    factor = e(k)/f(k­‐1);
    f(k) = f(k) – factor*g(k‐1);
    r(k) = r(k) – factor*r(k‐1);
end

% back substitution
x(n) = r(n)/f(n);
for k = n‐1:­‐1:1
    x(k) = (r(k)‐g(k)*x(k+1))/f(k);
end
4

1 回答 1

2

我绝不是 MATLAB 专家,但我会试一试。

我注意到您的代码索引范围内没有任何行。很好,这意味着我之前看到的每个操作都涉及一对数字。所以我认为第一个循环是每次迭代 5 FLOPS,第二个循环是每次迭代 3。然后是中间那个单一的操作。

但是,MATLAB 默认将所有内容存储为双精度值。因此,循环变量 k 本身在每个循环中运行一次,然后每次从中计算索引。所以这是第一个循环的额外 4 和第二个循环的 2。

但是等等——第一个循环有两次“k-1”,所以理论上可以通过计算和存储来优化它,每次迭代减少一个 FLOP 的数量。MATLAB 解释器可能能够为自己发现这种优化。据我所知,它可以计算出 k 实际上可以是一个整数,并且一切都还可以。

因此,您的问题的答案是视情况而定。您是否想知道 CPU 执行的 FLOP 数量,或代码中表示的最小数量(即仅对向量进行的操作数量),或者如果 MATLAB 根本不进行优化,它将执行的 FLOP 的严格数量? MATLAB 曾经有一个 flops() 函数来计算这类事情,但现在已经不存在了。无论如何,我都不是 MATLAB 专家,但我怀疑 flops() 已经消失了,因为解释器变得太聪明并且做了很多优化。

我有点想知道你为什么想知道。我曾经使用 flops() 来计算一个数学运算做了多少次运算,这是一种粗略的方法,可以粗略地估算我需要多少计算量才能使它实时工作,用 C 语言编写。

现在我看看原语本身(例如,有一个 1k 复数 FFT,根据库数据表,在那个 CPU 上将是 7us,有一个 2k 向量乘法,这将是 2.5us,等等)。这有点棘手,因为必须考虑缓存速度、数据集大小等。数学库(例如 fftw)本身实际上是不透明的,因此只能做到这一点。

因此,如果您出于这个原因计算 FLOP,您可能不会得到一个很好的答案。

于 2013-03-28T06:20:48.960 回答