[BUG] benchmark::DoNotOptimize does not prevent a reference from being optimized away.

未关闭
#1,773 4 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看

维护者通常 1 天内回复

还没有人认领这个 Issue。

评估

难度
4/5
预计耗时
3-5 天
新手友好度
35/100
Issue 类型
缺陷
描述清晰度
需要澄清
活跃度
停滞
技术栈
cpp
领域
performance

调研方向

从 benchmark::DoNotOptimize 开始,在 GCC 和 Clang 中编译提供的复现程序,比较循环中有引用和没有引用时生成的汇编。使用链接的 Compiler Explorer 示例验证行为;当语义得到确认并记录,或定义了具体更改时,该 issue 即完成。

由索引模型根据 Issue 内容生成。

描述

Describe the bug
benchmark::DoNotOptimize() does not prevent a reference from being optimized away.

System
OS: Ubuntu 20.04 LTS, Compiler explorer
Compiler: GCC 9.04, GCC trunk, Clang trunk

To reproduce
Compiler Explorer that works: https://godbolt.org/z/c3d5sc8s3
Compiler Explorer that does not: https://godbolt.org/z/3bMMvaecr

Alternatively, compile the following code

#include <vector>
#include <benchmark/benchmark.h>
static void bm_traverse(benchmark::State& state) {
    const size_t N = 500;
    std::vector<int> vec;
    for (size_t j = 0; j < N; ++j) vec.push_back(j);
    for (auto _ : state) {
        for (auto& value : vec) {
            asm("nop"); // just to locate asm point faster
            benchmark::DoNotOptimize(value);
        }
        benchmark::DoNotOptimize(vec);
    }
    state.SetComplexityN(N);
}
BENCHMARK(bm_traverse);
BENCHMARK_MAIN();

Expected behavior
DoNotOptimize should have preserved the loop read. I understand that the reference is basically a pointer but users typically would expect that the reference represents the actual lvalue.

Screenshots

With the "&" reference in the inner loop, a vec load is not generated.

.LBB0_31:                               #   Parent Loop BB0_6 Depth=1
        nop
        addq    $4, %rax
        cmpq    %rcx, %rax
        jne     .LBB0_31

If you remove the reference the vec load is generated.

.LBB0_31:                               #   Parent Loop BB0_6 Depth=1
        movl    (%rax), %edx   # <<<< HERE
        movl    %edx, 12(%rsp)
        nop
        addq    $4, %rax
        cmpq    %rcx, %rax
        jne     .LBB0_31

Additional context

I understand this is a matter of semantics that might have been discussed in the past. In this case, I'd just like confirmation of this behavior.

主要语言
C++
星标
10.5k
派生
1.8k
平均合并
1 天 15 小时
30 天内合并 PR
28

环境准备

  • 没有 Dockerfile 或 Docker Compose 文件
  • 没有 Pull Request 模板
  • 阅读贡献指南

从这里开始

  1. 先读完整个 Issue,再读项目的贡献指南。
  2. 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
  3. Fork 仓库,在一个分支上完成修改。
  4. 提交 Pull Request,并在描述里引用这个 Issue 编号。

google/benchmark 的其他 Issue

查看 google/benchmark 的全部 Issue

相似的 Issue

更多 C++ Issue

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。