你要使用的是AgnerFog的软件“Testprogramsformeasuring clock cycle and performancemonitoring”。他用这个软件来测量指令的延迟和吞吐量,以生成他著名的指令表。它有很好的文档记录,包括设备驱动程序(带有如何安装它们的说明),您可以在自己的代码中使用它们。这一点特别有用,因为为了测量某些量(如真实的CPU频率),您需要访问model specific registers (MSR),而用户级代码通常无法访问该model specific registers (MSR)。 编辑:根据您对面试问题的编辑,估计运行浮点密集型操作所需的时间,您可以使用以下公式:
time = efficiency * number_of_floating_point_operations / peak_flops.
5条答案
按热度按时间xjreopfe1#
这几乎肯定不是一个有用的度量标准。还有很多很多其他的东西与代码效率有关--尤其是缓存命中/未命中。
话虽如此,本主题中有一个ServerFault thread链接到您可以使用的Intel benchmarking suite,但您应该知道,您可能看不到系统的最大FLOPS与应用性能之间的任何关联。
wbgh16ku2#
你要使用的是AgnerFog的软件“Testprogramsformeasuring clock cycle and performancemonitoring”。他用这个软件来测量指令的延迟和吞吐量,以生成他著名的指令表。它有很好的文档记录,包括设备驱动程序(带有如何安装它们的说明),您可以在自己的代码中使用它们。这一点特别有用,因为为了测量某些量(如真实的CPU频率),您需要访问model specific registers (MSR),而用户级代码通常无法访问该model specific registers (MSR)。
编辑:根据您对面试问题的编辑,估计运行浮点密集型操作所需的时间,您可以使用以下公式:
许多处理器的每个内核的峰值flops可通过此链接flops-per-cycle-for-sandy-bridge-and-haswell-sse2-avx-avx2找到
这些量中的每一个都可能难以计算/估计,但效率是最困难的,因为它可能取决于许多因素,例如:
1.算法是计算还是内存受限?
1.算法使用SIMD(例如SSE/AVX/FMA)的能力如何?
1.算法使用MIMD(例如多核)的能力如何?
1.您的实施对不同缓存级别的使用情况如何?
为了更清楚地说明这一点,让我们考虑两种算法:矩阵乘法和点积。这两种算法的浮点运算次数很容易计算。矩阵乘法的浮点运算次数是
2*n*n*n
。点积的浮点运算次数是2*n。如果正确执行矩阵乘法,那么SIMD和MIMD可以充分利用它的计算能力。对于小n,它的效率开始较低,对于大n,它的效率将保持稳定。我自己的实现可以达到75%。英特尔® MKL可以达到95%以上(但使用FMA时不到90%)。
因此,对于较大的n,矩阵乘法的时间的包络线后估计是假设100%的效率,给出**
time = 2*n^3/peak_flops
。**然而,在一些情况下,对于点积,效率在小n时开始很高,在大n时下降到一个平台。这是因为它受内存限制。因此,对于大n,效率取决于内存的读取速度。对于现代机器,大约为10 GB/s。由于具有四核的现代台式机的峰值flops超过100 GLOPS,浮点数为4或8字节,因此我估计大型
n
的效率接近1%给出**time = 0.01*n/peak_flops
**。我继续进行测试(见下面的代码)。我的系统上得到大约2.2 GLOPS,峰值为236 GFLOPS,大约是峰值的1%。我的系统带宽大约为11 GB/s。大多数算法受内存限制,因此了解系统读取内存(DDR3、DDR4...)的速度是估计时间的最有用指标之一。
因此,一般来说,如果您知道某个算法的浮点运算数和处理器的峰值触发次数,首先应该问的是,对于较大的n,该算法是受计算限制还是受内存限制,然后对于时间的粗略估计,我会假设计算限制的效率为100%,而对于内存限制,我会查找带宽来估计效率。
此代码通过点积估计数据速率和GFLOPS。
tvokkenx3#
试图确定“在真空中”的FLOP所花费的时间没有多大意义,因为有很多其他因素影响它(操作数是否在存储器/高速缓冲存储器/寄存器中,它实际上是什么类型的操作,编译器是否发出x87/SSE/SSE 2/...指令,它是否涉及“奇怪的”IEEE 754值,处理器流水线是否被有效地使用,如果代码是分支预测器友好的,......)。
相反,您应该在算法的实际代码上使用分析器,以查看 * 真实的的 * 瓶颈是什么,以及 * 在您的特定代码 * 中 * 在这些瓶颈上实际花费了多少时间。
fcipmucu4#
有一个快速的方法,通过在做一些操作之前和之后获取时间戳,然后减去它们来查看消耗了多少时间。但是,这不是很准确。
7ivaypg95#
下面提供了一个关于可变性的想法,来自我的一个基准测试,它使用了长序列的相同汇编代码指令,试图填充流水线,不同的测试使用了可变数量的寄存器。