我对FLOP的定义进行了一些研究,并得到了一些相互矛盾的答案。其中最流行的答案之一是“1 FLOP = 一次加法和一次乘法运算”。这是真的吗?如果是这样,从物理上讲,这到底意味着什么?
无论我最终使用哪种方法,它都必须是可扩展的。代码的某些版本解决具有数百万未知数的系统,并需要几天才能执行。
在我的情况下(即“Fortran代码在数百个CPU上反复进行大量算术计算”的摘要),还有哪些其他有效的性能测量方法?
这是一种相当不错的性能度量,只要你确切地了解它所测量的内容。
FLOPS表示每秒浮点运算次数,正如名称所示。但实际上构成一个FLOP的内容可能因CPU而异(例如,有些CPU可以将加法和乘法视为一种操作,而其他CPU则不能)。这意味着作为一种性能度量,它与硬件非常接近,这意味着1)您必须知道您的硬件来计算给定架构上理想的FLOPS,并且必须知道您的算法和实现来确定它实际包含多少浮点操作。
无论如何,它是检查您如何利用CPU的有用工具。如果您知道CPU的理论峰值FLOPS性能,那么您可以计算出您使用CPU的浮点单位的效率,这通常是难以高效利用的单位之一。在CPU能力的30%运行的程序具有优化的余地。在70%运行的程序可能不会再变得更有效,除非您改变基本算法。对于像您的数学密集型算法,这几乎是衡量性能的标准方式。您可以简单地测量程序运行的时间,但这会因CPU而异。但是,如果您的程序的CPU利用率为50%(相对于峰值FLOPS计数),则这是一个更加恒定的值(它仍然会在不同的CPU架构之间有所变化,但比执行时间更为一致)。
但是,了解“我的CPU能够达到X GFLOPS,而我实际上只实现了其吞吐量的20%”是高性能软件中非常有价值的信息。这意味着除浮点运算以外的某些内容阻碍了您的效率,并且防止了FP单位有效地工作。由于FP单位占据大部分工作量,这意味着您的软件存在问题。
测量"My program runs in X minutes"很容易,如果你觉得不可接受,那么当然可以尝试减少30%,但是除非你准确地计算出有多少工作正在进行,以及CPU在峰值时的确切性能,否则你就不知道是否可能。如果你甚至不知道CPU基本上是否能每秒运行更多指令,你要花费多少时间来优化呢?
通过在FP操作之间具有太多依赖关系或具有太多分支或类似物以防止有效调度,很容易防止CPU的FP单元被有效利用。如果这正是阻碍你实现的原因,你需要知道 "我没有获得应该可能的FP吞吐量,因此显然我的代码中的其他部分正在阻止FP指令在CPU准备发出时可用。"
为什么需要其他方式来衡量性能? 按照老板的要求计算FLOPS是否有错呢?;)
我想补充几个细节:
除法是特殊的。由于大多数处理器可以在单个周期内执行加、比较或乘法,因此它们都被视为一个flop。但是除法总是需要更长的时间。具体需要多长时间取决于处理器,但在HPC社区中有一种约定俗成的标准,即将一个除法计为4个flop。
如果处理器有一个融合乘加指令,可以在单个指令中执行乘法和加法——通常是A += B * C——那么计为2个操作。
始终要小心区分单精度flop和双精度flop之间的差别。一个能够执行许多单精度gigaflops的处理器可能只能执行其中的一小部分双精度gigaflops。AMD Athlon和Phenom处理器通常可以执行一半的双精度flop与单精度flop相比。ATI Firestream处理器通常只能执行1/5的双精度flop与单精度flop相比。如果有人试图向您销售处理器或软件包,并且只引用了flop而没有说明是哪种精度的flop,您应该提醒他们。
诸如megaflop、gigaflop、teraflop等术语在常用中。这些术语指的是1000的倍数,而非1024。例如,1兆flop = 1,000,000 flop/sec而不是1,048,576。就像磁盘驱动器大小一样,这可能会引起一些混淆。
vdivps
不在关键路径上,其执行吞吐资源的成本与vmulps
相同。OoO exec可以隐藏延迟,并且对于前端而言只有1个uop(在某些CPU上),因此只要您不需要比非完全流水线化的除法器更频繁地进行除法运算即可处理。浮点除法与浮点乘法 - Peter Cordes这是一个老问题,有一些流行的答案,但在我看来并不完美。
“FLOP”是浮点数运算。 “FLOPS”可以指以下两种情况之一:
如果从上下文中无法明确是哪一种意思,通常通过将前者写为“FLOPs”而将后者写为“FLOP/s”来消除歧义。
所谓的FLOPs是为了区别于其他类型的CPU操作,例如整数运算、逻辑运算、位运算、内存操作和分支操作,它们具有不同的成本(即“需要不同的时间长度”)。
"FLOP计数"的实践可以追溯到科学计算的早期,相对而言,FLOP非常昂贵,每个FLOP需要很多CPU周期。例如,80387数学协处理器单次乘法需要大约300个周期。这是在流水线技术和CPU时钟速度与内存速度差距真正拉开之前:内存操作只需一两个周期,分支(“决策制定”)也同样便宜。在那个时候,如果你能够用十几个内存访问或分支来替代一个FLOP,你就会获得收益。因此,在过去,计算FLOP数量并不过多关注内存引用和分支是有意义的,因为FLOP在执行时间中占主导地位,因为它们相对于其他类型的操作来说非常昂贵。最近情况已经反转。FLOPs变得非常便宜 - 任何现代的英特尔核心每个周期可以执行大约两个FLOP(尽管除法仍然相对昂贵) - 而内存访问和分支相对更加昂贵:L1缓存命中可能需要3或4个周期,从主存储器获取则需要150-200个周期。考虑到这种反转,不再是以前通过消除FLOP来换取内存访问会产生收益;事实上,这是不太可能的。同样,即使FLOP是多余的,通常也更便宜“只是做”FLOP,而不是决定是否要执行它。这与25年前的情况完全相反。
很不幸,将盲目计算FLOP作为算法优劣的绝对度量已经过时。现代科学计算更多地涉及内存带宽管理——试图让执行FLOP的执行单元不断地获取数据——而不是减少FLOP数量。提到LINPACK(20年前基本上被LAPACK淘汰了)让我怀疑你的雇主可能是一个非常老派的学校,还没有内化建立性能期望不仅仅是FLOP计数的事实。如果具有更有利的内存访问模式和数据布局,则执行两倍FLOP的求解器仍然可能比另一个快20倍。FLOPS即浮点运算每秒。例如,如果您需要一秒钟完成一个操作(如将两个值相加、相减、相乘或相除,并返回结果),则您的性能就是1 FLOPS。最近的CPU可以轻松实现数十亿次浮点运算,即数十亿次浮点运算每秒。
我会尽可能地让它运行得更快,这需要找出它花费时间的地方,特别是如果有可以避免的函数调用。
我通过简单的方法来实现,就是在它运行时中断几次,看看它在做什么。以下是我发现的一些事情:
大部分时间都花在计算导数和/或雅可比矩阵上。其中很多时间都用于数学函数调用,例如exp()
、log()
和sqrt()
。通常这些函数会重复使用相同的参数,可以进行记忆化处理。(大幅加速)
由于积分容限比必要的更紧,因此很多时间都花在了计算过多次的导数上。(更快)
如果使用隐式积分算法(如DLSODE Gear),因为方程被认为是僵硬的,那么它们可能并不是僵硬的,可以使用类似龙格-库塔的算法(DVERK)。 (更快)
如果模型是线性的(DGPADM),则可能可以使用矩阵指数算法。这对性能和精度都有很大提升,并且不受僵硬性的影响。(更快)
在调用堆栈中更高层次上,可能会反复执行相同的积分,但参数略有不同,以确定解相对于这些参数的前向或中心差分梯度。如果微分方程本身是可微的,则可能通过解析地或通过增加灵敏度方程来获得这些梯度。这不仅更快,而且更精确,可以进一步提高堆栈上层的速度。
你可以将每一层堆栈视为寻找优化事项的机会,并且速度提升将不断累积。当您转向多CPU时,假设它是可并行的,那么它应该提供自己的乘法因子。
回到FLOPs。您可以尝试最大化每秒钟的FLOPs
,但通过在堆栈的所有级别上进行优化,最小化每次运行的FLOPs
也可以更有用。无论如何,只是测量它们几乎什么都告诉不了您。
你的雇主是对的。
衡量你的Fortran程序(或任何其他程序)有效性的唯一方法是测试它是否符合标准基准,如果有的话。
至于FLOPs,它代表“每秒浮点运算次数” - 可以在维基百科上看到定义。
我认为测量FLOPS并不是非常有用。
FLOPS的数量只能告诉您算法正在使CPU保持多忙,但不能告诉您算法本身表现如何。
您可能会发现两个不同的算法会导致处理器执行相同数量的FLOPS,但其中一个可以在一半的时间内提供您所需的结果。
我认为您最好关注更高级的统计数据,例如每单位时间解决的微分方程的数量(毕竟这是您的算法的目的)。
另一方面,测量实现的FLOPS数量可能有助于改善您的算法,因为它将告诉您CPU的繁忙程度。
如何测量T-FLOPS
"(# of parallel GPU processing cores multiplied by peak clock speed in MHz multiplied by two) divided by 1,000,000
公式中的数字2源于某些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年显卡价格比较: "这些是理论性能数据,我们了解到这些数据通常会过于乐观,高出实际数值的十倍。因此,根据这些数据,实际价格大约在每GFLOPS 0.03美元至0.3美元之间。我们收集了单精度和双精度的数据,但最便宜的价格相似。"