我正在编写一个程序来计算我的CPU执行一次"FLops"所需的持续时间。为此,我在下面写了代码
before = clock();
y= 4.8;
x= 2.3;
z= 0;
for (i = 0; i < MAX; ++i){
z=x*y+z;
}
printf("%1.20fn", ( (clock()-before )/CLOCKS_PER_SEC )/MAX);
问题是我在重复同样的操作。编译器不是在优化这种"东西"吗?如果是,我该怎么做才能得到正确的结果?
我没有使用"rand"函数,所以它不会与我的结果相冲突。
这有一个循环携带的依赖项,没有足够的东西可以并行执行,所以如果有任何东西被执行,那么你测量的就不是FLOP,这样你可能会测量浮点加法的延迟。循环携带的依赖链序列化所有这些添加。这个链有一些带乘法的小侧链,但它们不依赖于任何东西,所以只有它们的吞吐量才重要。但这种吞吐量将比任何合理处理器上添加的延迟都要好。
要真正测量FLOP,没有单一的配方。最佳条件在很大程度上取决于微体系结构。你需要的独立依赖链的数量,最佳的加法/复数比,你是否应该使用FMA,这一切都取决于你。通常,你必须做一些比你写的更复杂的事情,如果你决心使用一种高级语言,你必须以某种方式欺骗它,让它真正做任何事情。
为了获得灵感,请参阅我如何实现每个周期4个FLOP的理论最大值?
即使你没有进行编译器优化(可能性已经很好地列出),你的变量和结果也会在第一次循环迭代后被缓存,从那时起,如果程序必须为每次迭代获取新值,你的速度和性能会比现在更快。
因此,如果你想计算这个程序的一次迭代的一次失败的时间,你实际上必须为每次迭代提供新的输入。真的可以考虑使用rand(),只使用已知值srand(1)
左右的种子
您的计算也应该有所不同;flops是您的程序在您的情况下进行的计算次数2*n(其中n=MAX)。要计算每个触发器的时间量,请将使用的时间除以触发器的数量。