文档目录

一、为什么需要它们

编译器非常聪明,会优化掉"看起来没用的代码":

void test_sine() {
    double x = 0.0;
    for (int i = 0; i < 100000; i++) {
        x = sin(x);  // 编译器发现 x 没有后续使用 → 整个循环被删掉!
    }
}

// 如果你用 benchmark 测试这个函数,测出来时间 ≈ 0ns
// 因为编译器把整个循环优化掉了

二、正确用法

static void BM_Sine(benchmark::State& state) {
    double x = 0.0;

    for (auto _ : state) {
        x = sin(x);
        // 告诉编译器:这个值后续会被使用,不能删
        benchmark::DoNotOptimize(x);
    }

    // 最终把 x 输出,也是告诉编译器"x 确实被用了"
    std::cout << x << std::endl;
}

static void BM_Memcpy(benchmark::State& state) {
    char src[1024] = {}, dst[1024] = {};

    for (auto _ : state) {
        memcpy(dst, src, 1024);
        // 告诉编译器:dst 的内容被"外部"使用了
        benchmark::ClobberMemory();
    }
}

// 对比没有 ClobberMemory 的版本——编译器可能会把 memcpy 优化掉
static void BM_Memcpy_Wrong(benchmark::State& state) {
    char src[1024] = {}, dst[1024] = {};

    for (auto _ : state) {
        memcpy(dst, src, 1024);
        // dst 后续没被使用 → 编译器可能优化掉 memcpy
        // 测出来的时间 ≈ 0ns
    }
}