如何在C++中生成编译器不会删除的计算密集型代码

How to generate computation intensive code in C++ that will not be removed by compiler?

本文关键字:删除 计算 代码 密集型 编译器 C++      更新时间:2023-10-16

我正在做一些关于CPU性能的实验。我想知道是否有人知道一种正式的方法或工具来生成可以运行一段时间(几秒钟)并消耗大量CPU计算资源的简单代码。

我知道有很多CPU基准测试,但它们的代码相当复杂。我想要的是一个更直接的程序。

由于编译器非常聪明,按照以下方式编写一些多余的代码将不起作用。

for (int i = 0; i < 100; i++) {
    int a = i * 200 + 100;
}

将基准代码放在函数中,与调用它的代码分开。这可以防止代码内联,从而导致激进的优化。

使用固定值的参数(例如,要运行的迭代次数)并返回结果值。这可以防止优化器进行过多的常量折叠,并防止它取消对它确定永远不会使用的变量的计算。

以问题的例子为基础:

int TheTest(int iterations) {
    int a;
    for (int i = 0; i < iterations; i++) {
        a = i * 200 + 100;
    }
    return a;
}

即使在这个例子中,编译器仍然有可能意识到只有最后一次迭代才重要,并完全省略循环,只返回200*(iterations - 1) + 100,但我不希望在许多实际情况下发生这种情况。检查生成的代码以确定。

其他想法,比如在某些变量上使用volatile,可能会抑制一些合理的优化,这可能会使基准测试的性能比实际代码差。

还有一些框架,比如这个,用于编写这样的基准测试。

删除代码的不一定是优化器。现在的CPU非常强大,你需要提高挑战级别。然而,请注意,您的原始代码并不是一个好的通用基准:您只使用CPU指令集的一个子集。一个好的基准测试将尝试在不同类型的操作中挑战CPU,以预测现实世界场景中的性能。非常好的基准测试甚至会在计算机的各个组件上加载负载,以测试它们的相互作用。

因此,只需为您的问题使用一个众所周知的已发布基准即可。他们更多地参与其中是有充分理由的。然而,如果你真的只是想对你的设置和代码进行基准测试,那么这一次,只需要选择更高的计数器值:

  double j=10000;
  for (double i = 0; i < j*j*j*j*j; i++) 
  {
  }

这应该目前效果更好。请注意,还有更多的迭代。根据您的需要更改j。