You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

volatile与side effect是否相关?cppreference计时代码疑问

关于cppreference计时代码中volatile与side effect的疑问解答

问题1:注释的意图及与volatile sink的关系

注释make sure it's a side effect的核心目的就是强制让这行赋值操作成为编译器不能忽略的“副作用”,和volatile int sink直接绑定,本质就是为了防止编译器优化掉整个耗时操作链。

如果没有这个赋值或者sink不是volatile,编译器会发现:我们创建了vector、调用了accumulate,但最终计算出来的结果既没打印也没被后续代码使用——这种“无意义”的操作会被编译器直接优化掉,导致计时结果完全失真(可能显示耗时为0)。加上这行赋值并配合volatile,就是告诉编译器:这个计算结果必须被写到sink里,这个操作是有实际意义的,不能省略。

问题2:为什么要给sink加volatile修饰符

你可能觉得编译器能识别accumulate修改了sink,但编译器的优化逻辑比你想的更激进:如果sink是普通int,编译器会发现后续代码根本没用到sink的值,那std::accumulate的计算结果以及vector的创建都是“无用功”,会被直接优化删除。

而volatile的作用就是告诉编译器,对这个变量的读写操作是“不可优化”的——无论后续有没有用到它的值,对sink的赋值都必须执行。这样一来,为了完成这个赋值,编译器就必须保留前面的vector初始化和accumulate计算,计时才能准确反映真实的操作耗时。

volatile与side effect的关联

先明确两个核心概念:

  • side effect(副作用):指程序对外部状态的修改,比如修改全局变量、执行IO操作、调用有副作用的函数等。编译器会保证有副作用的操作不会被随意优化。
  • volatile:修饰的变量的读写本身就被视为一种side effect。编译器必须严格按照代码顺序执行对volatile变量的读写,不能省略、重排或合并这些操作。

回到这段代码:把sink设为volatile,就是让sink = std::accumulate(...)这行成为一个明确的side effect。因为要完成这个副作用,前面的vector创建和accumulate计算都是必要步骤,编译器就不会把它们优化掉,这样计时才能得到真实的操作时间。


附上相关代码

#include <iostream>
#include <iomanip>
#include <vector>
#include <numeric>
#include <chrono>
 
volatile int sink;
int main()
{
    std::cout << std::fixed << std::setprecision(9) << std::left;
    for (auto size = 1ull; size < 1000'000'000ull; size *= 100) {
        // record start time
        auto start = std::chrono::system_clock::now();
        // do some work
        std::vector<int> v(size, 42);

        // This is the line I mentioned.
        sink = std::accumulate(v.begin(), v.end(), 0u); // make sure it's a side effect

        // record end time
        auto end = std::chrono::system_clock::now();
        std::chrono::duration<double> diff = end - start;
        std::cout << "Time to fill and iterate a vector of " << std::setw(9)
                  << size << " ints : " << diff.count() << " s\n";
    }
}

内容的提问来源于stack exchange,提问作者starriet 차주녕

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 19:06:26