Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/140.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 谷歌基准测试结果中显示的时间毫无意义_C++_Benchmarking_Google Benchmark - Fatal编程技术网

C++ 谷歌基准测试结果中显示的时间毫无意义

C++ 谷歌基准测试结果中显示的时间毫无意义,c++,benchmarking,google-benchmark,C++,Benchmarking,Google Benchmark,我在我的处理器上基准测试了一些示例函数,每个核心运行在2GHz。以下是正在进行基准测试的功能。此外,可在 结果表明,前两个函数的执行时间分别为0.490ns和0.858ns。 然而,我不明白的是,如果我的核心运行在2GHz,这意味着一个周期是0.5ns,这使得结果看起来不合理 我知道显示的结果是迭代次数的平均值。如此低的执行时间意味着大多数样本低于0.5ns 我错过了什么 编辑1: 从评论中可以看出,将常量i添加到x似乎不是一个好主意。事实上,我首先在虚拟函数和非虚拟函数中调用std::cout

我在我的处理器上基准测试了一些示例函数,每个核心运行在2GHz。以下是正在进行基准测试的功能。此外,可在

结果表明,前两个函数的执行时间分别为
0.490ns
0.858ns
。 然而,我不明白的是,如果我的核心运行在2GHz,这意味着一个周期是
0.5ns
,这使得结果看起来不合理

我知道显示的结果是迭代次数的平均值。如此低的执行时间意味着大多数样本低于
0.5ns

我错过了什么

编辑1: 从评论中可以看出,将常量
i
添加到
x
似乎不是一个好主意。事实上,我首先在虚拟函数和非虚拟函数中调用
std::cout
。这有助于我理解虚拟函数不是内联的,需要在运行时解析调用

然而,在被基准标记的函数中有输出在终端上看起来并不好。(有没有办法分享我的Godbolt代码?)
有人能提出一种替代方法来打印函数内部的内容吗?

现代编译器的功能非常强大。不总是最可预测的事情,但通常是好事。 您可以通过按照建议观看ASM或降低优化级别来了解这一点。 Optim=1使非虚拟函数在CPU时间方面与virtualFunc相当,Optim=0将所有函数提升到一个类似的级别(编辑:当然是一种糟糕的方式;不要这样做是为了得出性能结论)


是的,当我第一次使用QuickBench时,我也被“DoNotOptimize”弄糊涂了。他们最好将其称为“UseResult()”,以表明在进行基准测试时它实际上打算假装什么。

最有可能的是,优化器在您的功能上完成了它的工作—您知道现代CPU中的支持吗?或者你只是惊讶于编译器将你的
非虚拟函数
简化为一条
add
指令(参见快速工作台链接中的程序集)?一个周期并不意味着它运行一条指令。你的CPU在一个周期内完成了很多事情。@斯塔克,我调用了函数benchmark::DoNotOptimize(),你的意思是这对编译器来说还不够吗?@talekeDskobeDa的意思是“编译器,请不要把我的代码简化为无操作,因为它实际上什么都不做”,而不是“编译器,请不要执行任何优化”.完全禁用优化以进行基准测试是一个糟糕的建议;这不是一个有效的建议。您的代码将有不同的瓶颈,即存储/重载C++语句之间的所有变量。(存储转发延迟)。这会产生各种奇怪的效果,比如。另请参见和。至少使用
-Og
-O1
,但最好至少使用
-O2
,最好使用
-O3
,并小心使用内联asm宏,如
DoNotOptimize
,以强制编译器在寄存器中具体化值,和/或忘记某个值,因此必须基于该值重新计算某些内容。e、 g.作为重复循环的一部分,使某事花费可测量的时间。请记住,您是在测量延迟(循环携带依赖性)还是吞吐量(独立,具有指令级并行性(ILP)),因为对于超标量无序CPU,单个指令具有吞吐量!=延迟。@PeterCordes-Ehm,我没有建议他禁用优化,然后从中得出性能方面的结论!然而,他可以使用这个切换来理解为什么代码在优化中表现得出奇地好。然而,总的来说,我会说,像那些需要几纳秒时间的小语句这样的小语句没有多大意义。如果您将一些主要的计算作为一个整体进行基准测试,那么您在项目中实际优化代码的机会会高得多。您提到的
optim=0
将所有函数提升到了类似的水平。如果不添加任何红色标志,如“(永远不要这样做,结果不会告诉您正常编译时的性能情况)”。人们经常会错误地认为,禁用优化使其基准不进行优化总比什么都不优化好。事实并非如此,所以在我看来,消除这种误解是一个好主意。老实说,我甚至写过“通过降低优化级别”,我很难下定决心去理解我的文章,但正如你所说。。。我将简要编辑。
#include <stdlib.h>
#include <time.h>
#include <memory>

class Base
{
  public:       
   virtual int addNumVirt( int x ) { return (i + x); }
   int addNum( int x ) { return (x + i); }
   virtual ~Base() {}

  private:
   uint32_t i{10};
};

class Derived : public Base
{
  public:
   // Overrides of virtual functions are always virtual
   int addNumVirt( int x ) { return (x + i); }
   int addNum( int x ) { return (x + i); }

  private:
   uint32_t i{20};
};

static void BM_nonVirtualFunc(benchmark::State &state)
{
 srand(time(0));
 volatile int x = rand();
 std::unique_ptr<Derived> derived = std::make_unique<Derived>();
 for (auto _ : state)
 {
   auto result = derived->addNum( x );
   benchmark::DoNotOptimize(result);
 }
}
BENCHMARK(BM_nonVirtualFunc);

static void BM_virtualFunc(benchmark::State &state)
{
 srand(time(0));
 volatile int x = rand();
 std::unique_ptr<Base> derived = std::make_unique<Derived>();
 for (auto _ : state)
 {
   auto result = derived->addNumVirt( x );
   benchmark::DoNotOptimize(result);
 }
}
BENCHMARK(BM_virtualFunc);

static void StringCreation(benchmark::State& state) {
  // Code inside this loop is measured repeatedly
  for (auto _ : state) {
    std::string created_string("hello");
    // Make sure the variable is not optimized away by compiler
    benchmark::DoNotOptimize(created_string);
  }
}
// Register the function as a benchmark
BENCHMARK(StringCreation);

static void StringCopy(benchmark::State& state) {
  // Code before the loop is not measured
  std::string x = "hello";
  for (auto _ : state) {
    std::string copy(x);
  }
}
BENCHMARK(StringCopy);
Run on (64 X 2000 MHz CPU s)
CPU Caches:
  L1 Data 32K (x32)
  L1 Instruction 64K (x32)
  L2 Unified 512K (x32)
  L3 Unified 8192K (x8)
Load Average: 0.08, 0.04, 0.00
------------------------------------------------------------
Benchmark                  Time             CPU   Iterations
------------------------------------------------------------
BM_nonVirtualFunc      0.490 ns        0.490 ns   1000000000
BM_virtualFunc         0.858 ns        0.858 ns    825026009
StringCreation          2.74 ns         2.74 ns    253578500
BM_StringCopy           5.24 ns         5.24 ns    132874574