48

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

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

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

在我的案例中,还有什么其他有效的测量性能的方法(我的案例总结是'fortran代码,它在数百个CPU上一遍又一遍地进行大量算术计算)?

4

9 回答 9

56

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

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

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

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

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

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

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

于 2008-11-30T18:53:45.227 回答
30

我只想补充几点:

  • 分工很特殊。由于大多数处理器可以在一个周期内进行加法、比较或乘法运算,因此这些都被计为一个触发器。但是分裂总是需要更长的时间。多长时间取决于处理器,但在 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。就像磁盘驱动器大小一样,对此也有一些混淆。

于 2008-11-30T19:53:48.927 回答
9

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

“FLOP”是浮点数学运算。“FLOPS”可能意味着以下两种情况之一:

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

在从上下文中不清楚的地方,通常通过将前者写为“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的引用(基本上已被LAPACK淘汰20 年前)让我怀疑你的雇主可能是一所非常古老的学校,没有内化这样一个事实,即建立绩效预期不再只是 FLOP 数的问题。如果具有更有利的内存访问模式和数据布局,则执行两倍 FLOP 的求解器仍可能比另一个快 20 倍。

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

所谓的屋顶线模型可能提供了一种更好的考虑性能期望和评估的方法,它远非完美,但具有让您考虑浮点和内存带宽问题之间权衡的优势。同时,提供更丰富、更有洞察力的“二维图片”,可以比较性能测量和性能预期。

值得一看。

于 2013-09-01T23:33:32.410 回答
4

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

FLOPS 意味着你需要

1) 每个工作单元的 FLOPs。

2) 该工作单元的时间。

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

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

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

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

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

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

可行的结果是什么?

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

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

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

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

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

于 2008-11-30T19:16:55.583 回答
1

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

于 2008-11-30T18:51:37.617 回答
1

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

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

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

  • 大部分时间都花在计算导数上,因为积分容差比必要的要小。(快点)

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

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

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

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

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

于 2009-06-12T18:01:05.020 回答
0

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

而且,关于 FLOP,它代表“每秒浮点运算”——参见 Wikipedia 上的定义

于 2008-11-30T18:52:19.580 回答
0

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

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

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

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

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

于 2008-11-30T19:06:07.387 回答
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 最大图形潜力的指标,我们使用该指标。

Let's see how we can use that formula to calculate the teraFLOPS in the Xbox One. The system's integrated graphics has 768 parallel processing cores. The GPU's peak clock speed is 853MHz. When we multiply 768 by 853 and then again by two, and then divide that number by 1,000,000, we get 1.31 teraFLOPS."

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


Price comparison of GPUs from 2016: "These are theoretical performance figures, which we understand to generally be between somewhat optimistic and ten times too high. So this data suggests real prices of around $0.03-$0.3/GFLOPS. We collected both single and double precision figures, but the cheapest were similar."

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

于 2020-10-07T14:59:21.170 回答