我很难掌握如何计算FLOPs。这一刻我以为我明白了,下一刻我就完全搞不懂了。如果有人能帮我解释一下,我将不胜感激。我看过关于这个主题的所有其他帖子,没有一个是用我熟悉的编程语言(我知道一些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的总数作为以下代码(MATLAB)中方程n
数量的函数。
% 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
我绝不是MATLAB专家,但我会试一试。
我注意到代码中没有一行索引向量的范围。很好,这意味着我看到的每一个运算都涉及到一对数字。所以我认为第一次循环是每次迭代5次,第二次是每次迭代3次。然后在中间有一个操作
但是,MATLAB默认将所有内容存储为双精度类型。所以循环变量k本身在每个循环中被操作一次然后每次从它计算一个索引。所以第一个循环多了4个,第二个循环多了2个。
但是等等-第一个循环有两次'k-1',所以理论上可以通过计算和存储来优化这一点,每次迭代减少一个flop的数量。MATLAB解释器可能能够为自己发现这种优化。据我所知,它可以算出k实际上是一个整数,并且一切都是正确的。
所以你的问题的答案是看情况而定。您想知道CPU的FLOPs数量,还是代码中表达的最小数量(即仅对矢量进行操作的数量),或者MATLAB在没有优化的情况下执行的严格FLOPs数量?MATLAB曾经有一个flops()函数来计算这类事情,但它不再存在了。我不是MATLAB专家,但我怀疑flops()已经消失了,因为解释器变得太聪明了,做了很多优化。
我有点想知道你为什么想知道。我曾经使用flops()来计算一段数学运算做了多少次,作为一种粗略的方法来估计我需要多少计算量才能使它在c语言中实时运行。
现在我看原语本身(例如,有一个1k的复杂FFT,根据库数据表,这将是7us在CPU上,有一个2k向量乘法,这将是2.5us,等等)。这有点棘手,因为必须考虑缓存速度、数据集大小等。数学库(例如fftw)本身实际上是不透明的,所以人们只能这样做。
因此,如果你因为这个原因而计算FLOPs,你可能不会得到一个很好的答案。