【问题标题】:What is FLOP/s and is it a good measure of performance?什么是 FLOP/s,它是衡量性能的好方法吗?
【发布时间】:2020-10-07 22:59:21
【问题描述】:

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

我对 FLOP 到底是什么进行了一些研究,得到了一些非常矛盾的答案。我得到的最受欢迎的答案之一是“1 FLOP = 加法和乘法运算”。真的吗?如果是这样,那么在物理上,这究竟意味着什么?

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

在我的案例中,还有哪些其他有效的衡量性能的方法(我的案例总结是“fortran 代码在数百个 CPU 上反复进行数天的大量算术计算)?

【问题讨论】:

    标签: performance benchmarking flops


    【解决方案1】:

    这是一个相当不错的性能衡量标准,只要您准确了解它衡量的是什么。

    顾名思义,FLOPS 是每秒浮点运算数,确切的构成 FLOP 的内容可能因 CPU 而异。 (例如,一些 CPU 可以将加法和乘法作为一项操作执行,而其他 CPU 则不能)。这意味着作为性能衡量标准,它非常接近硬件,这意味着 1)您必须了解您的硬件才能在给定架构上计算理想的 FLOPS,并且您必须了解您的算法和实现才能弄清楚如何它实际上包含许多浮点操作。

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

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

    衡量“我的程序在 X 分钟内运行”很容易,如果您认为这是不可接受的,那么可以肯定,您可以选择“我想知道我是否可以将其砍掉 30%”,但您不这样做 除非您确切地计算出正在完成的工作量以及 CPU 在峰值时的能力,否则知道这是否可能。如果您甚至不知道 CPU 从根本上是否能够每秒运行更多指令,您想花多少时间来优化它?

    很容易阻止 CPU 的 FP 单元被有效利用,因为 FP 操作之间有太多的依赖关系,或者有太多的分支或类似的东西妨碍了有效的调度。如果这就是阻碍您实施的原因,您需要知道这一点。您需要知道“我没有获得应有的 FP 吞吐量,因此很明显,我的代码的其他部分正在阻止 FP 指令在 CPU 准备发出一条指令时可用”。

    为什么需要其他方法来衡量绩效?按照老板的要求计算 FLOPS 数有什么问题? ;)

    【讨论】:

    • 感谢您的帮助!我不知道 CPU 架构设置了 FLOP 速率值。
    • 好吧,他们没有。他们所拥有的是明确限制每种类型的指令需要多长时间,以及多久可以发出一条指令(以及其中有多少可以并行运行)。由此,您可以推导出理论峰值 FLOPS。
    • 根据 jalf 的最后一条评论,请记住,从 CPU 中获得峰值 FLOPS 非常困难,因为这意味着您的计算结构使得每个周期都能获得完整的 FP 问题。实际应用程序并非总是如此,但它确实让您了解如果您的代码受到计算限制,您可以获得多少潜在的性能改进。如果您想了解更多关于如何测量超级计算机的 FLOPS,请查看 Top500.org 的做法:top500.org/faq。他们在该页面上解释了他们的基准。
    • @caglarozdag:正如@tgamblin 所说,您通常可以忘记在任何 CPU 上达到峰值 FLOPS。它只是不会发生。在我见过的大多数应用程序中,如果你达到 CPU 理论峰值 FLOPS 的 50%,你应该拍拍自己的后背。也许你能达到 70%,但你真的应该认为自己很幸运。但是,如果您的运行速度为 10%(这种情况经常会出人意料地出现),则可能还有一些改进空间。
    • 附带但相关的问题:为什么以每秒 FLOPs (FLOPS) 衡量性能,为什么不考虑每秒整数操作数?
    【解决方案2】:

    我想补充几点:

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

    • 如果处理器具有融合乘加指令,该指令在单个指令中执行乘法和加法(通常为 A += B * C),则计为 2 次操作.

    • 始终小心区分单精度触发器和双精度触发器。能够处理这么多单精度 gigaflops 的处理器可能只能处理那么多双精度 gigaflops 的一小部分。 AMD Athlon 和 Phenom 处理器的双精度触发器通常是单精度触发器的一半。 ATI Firestream 处理器的双精度触发器通常是单精度触发器的 1/5。如果有人试图向您推销处理器或软件包,而他们只是引用失败而没有说明是哪一个,您应该打电话给他们。

    • megaflop、gigaflop、teraflop 等术语很常用。这些是指 1000 的因数,不是 1024。例如,1 megaflop = 1,000,000 flop/sec 而不是 1,048,576。就像磁盘驱动器大小一样,这也有一些混淆。

    【讨论】:

    • 你有一个引用是特殊的 / 算作 4 次翻牌吗?很想详细阅读。
    • @mprat:除法和乘法之间的成本比取决于您如何使用它。对于现代 CPU(自 2015 年以来)来说,“4 flops”听起来很虚假。偶尔出现的 x86-64 AVX vdivps 不在延迟成本的关键路径上,其执行吞吐量资源与vmulps 大致相同。 OoO exec 可以隐藏延迟,并且它对于前面只有 1 uop(在某些 CPU 上),所以只要您不需要比非完全流水线分隔器可以处理的更频繁地划分。 Floating point division vs floating point multiplication
    【解决方案3】:

    IMO,旧的问题,如果流行,答案不是很好。

    “FLOP”是浮点数学运算。 “FLOPS”可以表示以下两种情况之一:

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

    如果从上下文中不清楚,通常将前者写成“FLOPs”,将后者写成“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提供了一种更好的考虑绩效期望和评估的方法,它远非完美,但有一个优点是让你考虑浮动-之间的权衡同时解决点和内存带宽问题,提供更丰富、更有洞察力的“二维图片”,可以比较性能测量和性能预期。

    值得一看。

    【讨论】:

    • 总体不错的答案;一个挑剔:L1 缓存命中可能需要 3 或 4 个周期 - 这是近似的 延迟(更像是 Haswell/Skylake 上的 SIMD FP 加载需要 5 或 6 个周期) ,但它以每个时钟吞吐量 2 个负载流水线化。乱序执行可以轻松隐藏大多数代码中的 L1d 命中延迟(其中数组索引不依赖于先前的 FP 计算),这就是我们有 OoO 执行的原因。
    【解决方案4】:

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

    FLOPS 意味着你需要

    1) 每个工作单元的 FLOPs。

    2) 该工作单元的时间。

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

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

    您可以计算平方根,但您不知道它在乘法和加法方面的真正作用。因此,您必须执行基准乘法与平方根之类的操作,以了解平方根需要多长时间。

    现在您知道循环中的 FLOPS。而且您知道运行 1,000 次的时间。你知道每秒 FLOPS。

    然后您查看 LINPACK 并发现您的速度较慢。怎么办?你的程序不是 LINPACK,它比 LINPACK 慢。很有可能您的代码会变慢。除非您的代码是在与 LINPACK 相同的年数内编写和优化的,否则您会变慢。

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

    可行的结果是什么?

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

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

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

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

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

    【讨论】:

    • 我相信 LINPACK 解决了矩阵系统(LINPACK 的开发人员当时选择了一个有点武断的问题),巧合的是我们的算法具有基本相同的目的。我想我的老板意识到它会比 LINPACK 慢,只是想看看慢多少。
    • FLOPS 对于一个特定目的非常有用:测量 CPU FP 单元的利用率。而且由于这通常很难有效利用,因此 FLOPS 是 HPC 的有用信息。它告诉您程序的结构阻碍了对最重要的 CPU 资源的有效利用。
    【解决方案5】:

    正如您所说,FLOPS 是每秒一次的浮点运算。举个例子,如果你只用一秒钟的时间进行一个操作(比如加、减、乘或除两个值并返回结果),你的性能只是 1 FLOPS。最近的 CPU 可以轻松实现数 GigaFLOPS,即每秒数十亿次浮点运算。

    【讨论】:

      【解决方案6】:

      我只想让它尽可能快地运行,这需要找出它在哪里花费时间,特别是如果有可以避免的函数调用。

      我通过简单的方法来做到这一点,即在它运行时中断它几次,然后看看它在做什么。以下是我发现的类型:

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

      • 大部分时间都花在计算导数上,因为积分容差过于严格。 (更快)

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

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

      • 调用堆栈的更高层,可能是相同的积分使用略有不同的参数重复执行,以确定解决方案相对于这些参数的前向或中心差梯度。如果微分方程本身是可微的,则可以通过解析方式或通过使用灵敏度方程增加方程来获得这些梯度。这不仅更快,而且更精确,这可以加快堆栈中更高的速度。

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

      回到翻牌圈。您可以尝试最大化 FLOPs / second,但通过在堆栈的所有级别进行优化,最小化 FLOPs / run 也可能更有用。无论如何,仅仅测量它们几乎不会告诉你什么。

      【讨论】:

        【解决方案7】:

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

        关于 FLOP,它代表“每秒浮点运算” - 请参阅 Wikipedia 上的 definition

        【讨论】:

          【解决方案8】:

          我认为衡量 FLOPS 不会很有用。

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

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

          我认为您最好查看一个“更高级别”的统计数据,例如每单位时间求解的微分方程的数量(毕竟,这就是您算法的目的)。

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

          【讨论】:

          • FLOPS 显示您当前的实现距离相同算法的最佳实现还有多远。是的,如果你知道一个更有效的算法,你应该使用它,但希望你已经在使用最知名的算法,然后 FLOPS 在优化它时很重要。是的,它很有用
          【解决方案9】:

          如何衡量 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 的价格比较: “这些是理论上的性能数据,我们认为这些数据通常在有些乐观和高出十倍之间。因此,这些数据表明实际价格约为 0.03-0.3 美元/GFLOPS。我们收集了单精度和双精度数据,但最便宜的数据相似。”

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

          【讨论】:

            猜你喜欢
            • 2010-12-05
            • 2020-07-20
            • 2011-12-05
            • 1970-01-01
            • 1970-01-01
            • 2010-09-06
            • 2015-07-31
            相关资源
            最近更新 更多