2

我正在尝试std::isdigit从标头中对函数进行基准测试(为了清楚起见,从Ccctype继承的函数)。

代码片段如下:

void BM_IsDigit_C(::benchmark::State& state) {
  const char c = GenerateRandomChar();
  for (auto _ : state) {
    ::benchmark::DoNotOptimize(std::isdigit(static_cast<unsigned char>(c)));
  }
}
BENCHMARK(BM_IsDigit_C);

很容易推断这GenerateRandomChar是一个简单的函数,它会生成随机数char,并且不会给基准测试本身带来任何开销。


"""不幸的是""",编译器能够完全优化代码。它正确地生成了预期的代码std::isdigit,但是,在基准测试的汇编代码中,基本块被忽略了。

以下是分析生成的代码(由gcc-10.1.0):

性能报告

如您所见,std::isdigit代码已生成(编译器资源管理器示例):

movzbl %r13b,%eax 
sub    $0x30,%eax
cmp    $0x9,%eax
setbe  %al     
movzbl %al,%eax

但由于循环,它被完全忽略:

68: sub    $0x1,%rbx   <---|
    jne    68        ------|

小笔记

C++版本”(带语言环境)生成预期代码:测试函数代码的循环。

性能代码 C++


我的问题是:

  • 为什么benchmark::DoNotOptimize不适用于此特定功能?
  • 我如何更改基准代码以正确测量该功能的时间性能?
最后的笔记
  • 我在clang编译器上遇到了同样的“问题”。
  • 我试图将测试的函数“移动”到另一个翻译单元(强制非内联属性),但我遇到了同样的“问题”。
4

0 回答 0