什么是FLOP / s并且它是一个很好的性能衡量标准?

时间:2008-11-30 18:41:19

标签: performance benchmarking flops

我被要求测量在多CPU系统上解决微分方程的fortran程序的性能。我的雇主坚持要求我测量FLOP / s(每秒浮动操作数)并将结果与​​基准(LINPACK)进行比较,但我不相信它是要走的路,因为没有人可以向我解释什么是FLOP是。

我做了一些关于FLOP究竟是什么的研究,我得到了一些相当矛盾的答案。我得到的最受欢迎的答案之一是'1 FLOP =加法和乘法运算'。真的吗?如果是这样,再次,在物理上,究竟是什么意思?

无论我最终使用哪种方法,都必须具有可扩展性。一些版本的代码解决了具有数百万未知数的系统,并且需要数天才能执行。

在我的案例中,有哪些其他有效的衡量绩效的方法(我的案例摘要是'在几百个CPU上反复进行大量算术计算的fortran代码)?

9 个答案:

答案 0 :(得分:47)

只要你完全明白它的衡量标准,这是一个相当不错的衡量标准。

FLOPS,顾名思义是FLoating point OPerations per second,究竟是什么构成FLOP可能因CPU而异。 (某些CPU可以执行加法和乘法作为一个操作,其他CPU不能,例如)。这意味着作为一种性能指标,它与硬件非常接近,这意味着1)您必须知道您的硬件才能在给定的架构上计算理想的FLOPS,并且您必须了解您的算法和实现以了解如何它实际上由许多浮点运算组成。

在任何情况下,它都是检查您如何利用CPU的有用工具。如果您知道CPU在FLOPS中的理论峰值性能,您可以计算出使用CPU的浮点单元的效率,这通常是难以有效利用的单元之一。运行CPU能够运行30%FLOPS的程序具有优化空间。除非您更改基本算法,否则以70%运行的可能不会更有效率。对于像你这样的重数学算法,这几乎是衡量性能的标准方法。您可以简单地测量程序运行所需的时间,但这会因CPU而异。但是,如果您的程序具有50%的CPU利用率(相对于峰值FLOPS计数),那么这是一个更加恒定的值(它在不同的CPU体系结构之间仍然会有所不同,但它比执行时间更加一致)。 / p>

但是知道“我的CPU能够实现X GFLOPS,而我实际上只实现了20%的吞吐量”,这在高性能软件中是非常非常有价值的信息。这意味着其他比浮点操作更能阻止你,并阻止FP单元高效工作。由于FP单元构成了大部分工作,这意味着您的软件存在问题。

很容易衡量“我的程序在X分钟内运行”,如果你认为这是不可接受的,那么你可以去“我想知道我是否可以砍掉30%的折扣”,但你不会知道是否可能,除非你确切地知道正在做多少工作,以及CPU能够达到峰值的能力。如果您甚至不知道CPU是否能够从根本上每秒运行更多指令,那么您希望花多少时间来优化它?

通过在FP操作之间具有太多依赖关系,或者通过具有太多分支或类似因素来阻止有效调度,很容易防止CPU的FP单元被有效利用。如果这就是让你的实现恢复的原因,你需要才能知道。您需要知道“我没有获得应该可能的FP吞吐量,所以很明显我的代码的其他部分阻止了FP指令在CPU准备发布时可用”。

为什么还需要其他方法来衡量效果?你的老板要求你制定FLOPS计数有什么问题? ;)

答案 1 :(得分:26)

我想补充几点:

  • 分区很特别。由于大多数处理器可以在一个周期内进行加法,比较或乘法,因此这些都被算作一次翻转。但分裂总是需要更长时间。多长时间取决于处理器,但HPC社区中有一种事实上的标准,将一个部门计为4次失败。

  • 如果处理器有一个融合乘法 - 加指令,它在一条指令中进行乘法和加法 - 通常为A + = B * C - 计为2次运算

  • 要始终注意区分单精度触发器和双精度触发器。能够实现如此多单精度千兆位的处理器可能只能实现许多双精度千兆位的一小部分。 AMD Athlon和Phenom处理器的双精度触发器通常可以达到单精度的一半。 ATI Firestream处理器通常可以使用单精度的1/5双精度触发器。如果有人试图向你出售处理器或软件包而他们只是引用翻牌而不说哪些,你应该用它来打电话。

  • 术语megaflop,gigaflop,teraflop等是常用的。这些是指 1000 不是1024 的因素。例如,1兆浮点数= 1,000,000翻牌/秒不是1,048,576。就像磁盘驱动器大小一样,这有一些混乱。

答案 2 :(得分:3)

“将结果与基准进行比较”并做什么?

FLOPS意味着你需要

1)每个工作单元的FLOP。

2)该工作单元的时间。

假设您有一些输入文件通过某个循环执行1,000次迭代。循环是一个方便的工作单位。它被执行了1000次。这需要一个小时。

循环有一些加法和乘法以及一些除法和平方根。您可以计算加法,乘法和除法。您可以在源代码中查找,查找+,*和/。您可以从编译器中找到汇编语言输出,并在那里计算它们。你可能得到不同的数字。哪一个是对的?问你的老板。

你可以计算平方根,但你不知道它在乘法和加法方面的确是做什么的。因此,您必须执行基准乘法与平方根之类的操作,以了解平方根所需的时间。

现在您知道循环中的FLOPS了。而且你知道运行它的时间是1000次。你知道每秒FLOPS。

然后你看看LINPACK,发现你慢了。怎么办?你的程序不是LINPACK,它比LINPACK慢。你的代码速度慢的可能性非常大。除非你的代码是在LINPACK的相同年份内编写和优化的,否则你会慢一些。

这是另一部分。您的处理器对各种基准测试有一些定义的FLOPS评级。您的算法不是那些基准之一,因此您没有达到基准。这不好吗?或者这是不成为基准的明显后果?

可行的结果是什么?

针对某些基准代码库的测量只会告诉您,您的算法不是基准算法。你将会有所不同,这已成定局;通常比较慢。

显然,针对LINPACK的测量结果将是(a)你不同,因此(b)你需要优化。

在对你自己进行测量时,测量才真正有价值。不是一些假设的指令组合,而是你自己的指令组合。衡量自己的表现。做出改变。看看你的表现 - 与你相比 - 是好还是坏。

FLOPS并不重要。重要的是每单位工作的时间。您永远不会匹配硬件的设计参数,因为您没有运行硬件设计人员所期望的基准测试。

LINPACK并不重要。重要的是您的代码库以及您为改变性能所做的更改。

答案 3 :(得分:2)

老问题,如果很受欢迎,答案不是很好,IMO。

“FLOP”是浮点数学运算。 “FLOPS”可能意味着两件事:

  • 简单的复数“FLOP”(即“操作 X 需要50个FLOP”)
  • 第一种意义上的FLOP的速率(即每秒的浮点数学运算)

如果从上下文中不清楚,通过将前者称为“FLOP”而后者称为“FLOP / s”,通常会消除这些中的哪一个。

所谓的FLOP是为了区别于其他类型的CPU操作,例如整数运算,逻辑运算,按位运算,内存运算和分支运算,它们具有不同的成本(读取与他们相关的“花费不同的时间”。

“FLOP计数”的实践可以追溯到科学计算的早期阶段,相对而言,FLOP非常昂贵,每个都需要很多CPU周期。例如,80387数学协处理器为单个乘法采用了300个周期。这是在流水线化之前和CPU时钟速度与内存速度之间的鸿沟真正开放之前的时间:内存操作只花了一两个周期,而分支(“决策制定”)同样便宜。那时,如果你可以消除单个FLOP而支持十几次内存访问,那么你就获得了收益。如果您可以取消单个FLOP而不是十几个分支,那么您就获益了。所以,在过去,计算FLOP并且不必担心内存引用和分支是有意义的,因为FLOP强烈地占据了执行时间,因为它们相对于其他类型的操作来说单独非常昂贵。

最近,情况已经逆转。 FLOP变得非常便宜 - 任何现代的英特尔核心每个周期都可以执行大约两个FLOP(虽然分区仍然相对昂贵) - 并且内存访问和分支相对更昂贵:L1缓存命中成本可能是3或者4个周期,从主存储器中取出成本为150-200。鉴于这种反转,不再是消除FLOP而支持内存访问将导致增益;事实上,这不太可能。同样,“只做”FLOP通常更便宜,即使它是多余的,而不是决定是否这样做。这与25年前的情况完全相反。

不幸的是,盲目FLOP计数作为算法优点的绝对度量的做法一直持续到其销售日期。 现代科学计算更多的是关于内存带宽管理 - 试图保持执行单元 FLOP持续提供数据 - 而不是减少FLOP的数量。对 LINPACK 的引用(20年前基本上被 LAPACK 淘汰)让我怀疑你的雇主可能是一个非常老的学校,没有内化这个事实建立绩效期望不仅仅是FLOP计算的问题。如果具有更有利的内存访问模式和数据布局,那么执行FLOP两倍的解算器仍然可以比另一个快20倍。

所有这些的结果是,计算密集型软件的性能评估变得比过去复杂得多。。由于存储器操作和分支成本中的大量可变性,FLOP变得便宜的事实非常复杂。在评估算法时,简单的FLOP计数根本不能告知整体性能预期。

所谓的roofline model或许是一种更好的思考绩效期望和评估的方式,这种方法远非完美,但其优势在于让你思考之间的权衡。同时浮点和内存带宽问题,提供更具信息性和洞察力的“2D图片”,可以比较性能测量和性能预期。

值得一看。

答案 4 :(得分:1)

如你所说,FLOPS是每秒一次的浮点运算。例如,如果您只需一秒钟进行操作(例如添加,减去,乘以或除以两个值并返回结果),那么您的性能就是1 FLOPS。最近的CPU很容易实现几个GigaFLOPS,即每秒几十亿个浮点运算。

答案 5 :(得分:1)

我会尽量让它尽可能快地完成,这需要找出花费时间的地方,特别是如果有可以避免的函数调用的话。

我通过简单的方法来执行此操作,只需在运行时中断它几次,并查看它在做什么。以下是我发现的各种事物:

  • 大部分时间是在计算衍生物和/或雅可比行列式的过程中。大部分时间都可以进入数学函数调用,例如exp()log()sqrt()。通常这些都以相同的参数重复,并且可以被记忆化。 (大规模加速。)

  • 大部分时间用于计算衍生物的次数太多,因为积分公差比必要的更严格。 (更快)

  • 如果使用隐式积分算法(例如DLSODE Gear),因为方程被认为是僵硬的,那么它们可能不是,并且可以使用Runge-Kutta之类的东西。 (DVERK)。 (更快)

  • 如果模型是线性的(DGPADM),则可以使用矩阵指数算法。这对于性能和精度都是一个巨大的胜利,并且不受刚度的影响。 (方式更快)

  • 在调用堆栈的上方,可能是使用稍微不同的参数重复执行相同的集成,以便确定解决方案相对于那些参数的前向或中心差异梯度。如果微分方程本身是可微分的,则有可能通过分析得到这些梯度,或者通过用灵敏度方程增加方程。这不仅速度快得多,而且更加精确,可以加快堆栈的速度。

您可以将堆栈的每个级别视为查找要优化的内容的机会,并且加速将加速。然后当你去多CPU时,假设它是可并行化的,那应该提供它自己的乘法因子。

回到FLOP。您可以尝试最大化 FLOPs / second,但对于最小化 FLOPs / run,通过优化堆栈的所有级别,它也会更有用。在任何情况下,只需测量它们几乎不会告诉你任何事情。

答案 6 :(得分:0)

您的雇主是对的。
测量Fortran程序(或任何其他程序,btw)的有效性的唯一方法是根据标准基准测试它(如果存在的话)。

而且,关于FLOP,它代表“每秒浮点运算” - 请参阅维基百科上的definition

答案 7 :(得分:0)

我认为测量FLOPS不会非常有用。

实现的FLOPS数量将告诉您算法保持CPU的繁忙程度,但不会告诉您算法本身的执行情况。

您可能会发现两种不同的算法会导致处理器执行相同数量的FLOPS,但其中一种算法会在一半的时间内为您提供所需的结果。

我认为你最好看一个更高级别的统计数据,例如每单位时间内解决的微分方程的数量(毕竟,算法的目的)。

另一方面,测量FLOPS的数量可以帮助您改进算法,因为它会告诉您保持CPU的繁忙程度。

答案 8 :(得分:0)

如何测量T-FLOPS

"(# of parallel GPU processing cores multiplied by peak clock speed in MHz multiplied by two) divided by 1,000,000

公式中的第二个原因是某些GPU指令每个周期可以执行两次操作,并且teraFLOP是衡量GPU最大图形潜力的一种度量,因此我们使用该指标。

让我们看看如何使用该公式来计算Xbox One中的teraFLOPS。 该系统的集成图形具有768个并行处理核心。 GPU的峰值时钟速度为853MHz。当我们将768乘以853然后再乘以2,然后将该数字除以1,000,000时,我们得到1.31 teraFLOPS。”

https://www.gamespot.com/gallery/console-gpu-power-compared-ranking-systems-by-flop/2900-1334/


2016年以来GPU的价格比较: “这些是理论上的性能数据,我们认为通常在某种程度上介于10倍之间。因此,该数据表明实际价格约为$ 0.03- $ 0.3 / GFLOPS。我们收集了单精度和双精度数字,但最便宜的数字相似。”

https://aiimpacts.org/current-flops-prices/