所谓"fp运算“是指”浮点运算“。我在做一个Linux机器。是否有一个系统调用将此值作为静态度量返回,或者您可以用C/C++/其他语言的算法来测试这个值?
编辑:我应该提到,这不是为了测试代码的效率。在一次采访中,我被问到一个理论算法需要多长时间才能运行。我必须计算出要执行多少次失败,并在每一次操作得出粗略估计时将其乘以。我只是觉得这是个有趣的问题。
发布于 2014-07-31 07:55:12
您想要使用的是Agner的软件“测量时钟周期和性能监测的测试程序”。这是他用来测量指令延迟和吞吐量的方法,以生成他著名的指令表。它有详细的文档,包括设备驱动程序(以及如何安装它们的说明),您可以在自己的代码中使用这些驱动程序。这特别有用,因为为了测量某些数量,例如实际的CPU频率,您需要访问用户级代码通常无法访问的模型专用寄存器(MSR)。
编辑:根据您对面试问题的编辑来估计运行浮点密集型操作所需的时间,您可以使用以下公式:
time = efficiency * number_of_floating_point_operations / peak_flops.许多处理器的每个核心的峰值触发器可以从这个链接flops-per-cycle-for-sandy-bridge-and-haswell-sse2-avx-avx2中找到。
这些数量中的每一个可能都很难计算/估计,但效率是最困难的,因为它可能取决于许多事情,例如:
为了更清楚地说明这一点,让我们考虑两个算法:矩阵乘法和点积。对于这两种算法来说,浮点运算的次数很容易计算。矩阵乘法的浮点运算数为2*n*n*n。对于点积,它是2*n。
矩阵乘法,如果做的正确,它是计算界,可以充分受益于SIMD和MIMD。对于小n,它的效率很低,对于大n,它的效率很低,我自己的实现达到75%。英特尔MKL获得超过95% (但不到90%使用FMA)。
因此,对于大n的矩阵乘法时间的后包络估计是假定100%的效率,给出了time = 2*n^3/peak_flops**.**。
然而,对于点乘积,对于小n,效率会很高,而对于大n,效率会下降到一个平台,这是因为它是内存绑定的。因此,对于大的n,效率取决于存储器的读取速度。对于一台大约10 GB/s的现代机器。由于一个有四个核心的现代桌面将有一个峰值触发器,超过100个GLOPS,浮点数为4或8个字节,所以我估计大型time = 0.01*n/peak_flops.的效率接近1%。我进行了测试(请参阅下面的代码)。在我的系统上,我得到了大约2.2个GLOPS,峰值为236 GFLOPS,这大约是峰值的1%。我的系统带宽约为11 GB/s。
大多数算法都是内存绑定的,因此知道系统读取内存的速度(DDR3,DDR4,.)是估计时间的最有用的指标之一。
所以一般来说,如果你知道一个算法的浮点运算的数量和处理器的峰值触发器,你首先要问的是,如果算法是计算界还是内存界是大n,那么对于一个信封后估计时间,我假设效率是100%,对于计算界和内存界,我将查找带宽来估计效率。
此代码估计来自点积的数据速率和GFLOPS。
#include <time.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stdint.h>
float dot(float *x, float *y, int n) {
float sum = 0;
for(int i=0; i<n; i++) {
sum += x[i]*y[i];
}
return sum;
}
int main(){
const int LEN = 1 << 28;
float *x = new float[LEN];
float *y = new float[LEN];
for(int i=0; i<LEN; i++) { x[i] = 1.0*rand()/RAND_MAX - 0.5; y[i] = 1.0*rand()/RAND_MAX - 0.5;}
uint32_t size = 2*sizeof(float)*LEN;
clock_t time0 = clock();
float sum = dot(x,y,LEN);
clock_t time1 = clock();
double dtime = (double)(time1 - time0) / CLOCKS_PER_SEC;
double rate = 1.0*size/dtime*1E-9;
double flops = 2.0*LEN/dtime*1E-9;
printf("sum %f, dtime %f, rate %f, flops %f\n", sum, dtime, rate,flops);
}发布于 2014-07-30 23:56:24
这几乎肯定不是一个有用的指标。很多,很多其他的事情都会影响代码的效率--尤其是高速缓存的命中/错过。
尽管如此,有一个关于这个主题的ServerFault螺纹链接到您可以使用的英特尔基准套件,但是您应该知道,您可能不会看到系统的最大失败与应用程序的性能之间有任何关联。
发布于 2014-07-31 00:00:06
尝试确定“真空中”触发器所花费的时间是没有什么意义的,因为影响它的因素还有很多(操作数是否在内存/缓存/寄存器中,它实际上是什么类型的操作,如果编译器发出X87/SSE/SSE 2/.说明是否涉及“奇怪”的IEEE754值,如果有效地使用处理器管道,如果代码是分支预测器友好的,.)。
相反,您应该在算法的实际代码上使用分析器,查看哪些是真正的瓶颈,以及在特定代码中实际花费了多少时间在这些瓶颈上。
https://stackoverflow.com/questions/25048828
复制相似问题