为什么不应该使用"volatile"类型的类 【ChatGPT】

简介: 为什么不应该使用"volatile"类型的类 【ChatGPT】

为什么不应该使用"volatile"类型的类

C程序员通常认为volatile意味着变量可以在当前执行线程之外被改变;因此,当使用共享数据结构时,他们有时会倾向于在内核代码中使用它。换句话说,他们已经将volatile类型视为一种简单的原子变量,但实际上并非如此。在内核代码中几乎从不正确地使用volatile;本文描述了其中的原因。

理解volatile的关键点是,它的目的是抑制优化,而这几乎从不是我们真正想要做的。在内核中,我们必须保护共享数据结构免受不希望的并发访问,这是完全不同的任务。保护不希望的并发性的过程也会以更高效的方式避免几乎所有与优化相关的问题。

与volatile类似,使并发访问数据安全的内核原语(自旋锁、互斥锁、内存屏障等)旨在防止不希望的优化。如果它们被正确使用,就不需要再使用volatile。如果仍然需要volatile,那么代码中几乎肯定存在bug。在编写正确的内核代码中,volatile只会减慢速度。

考虑一个典型的内核代码块:

spin_lock(&the_lock);
do_something_on(&shared_data);
do_something_else_with(&shared_data);
spin_unlock(&the_lock);

如果所有的代码都遵循锁定规则,那么在持有the_lock时,shared_data的值不会意外改变。任何想要操作该数据的其他代码都将在锁上等待。自旋锁原语充当内存屏障 - 它们明确地被编写为如此 - 这意味着数据访问不会在它们之间进行优化。因此,编译器可能认为它知道shared_data中的内容,但是spin_lock()调用,由于它充当内存屏障,将迫使它忘记它所知道的任何内容。对该数据的访问不会出现优化问题。

如果shared_data被声明为volatile,那么锁定仍然是必要的。但是编译器也将阻止在临界区内对shared_data的访问进行优化,因为我们知道没有其他人会与之一起工作。在持有锁时,shared_data不是volatile的。在处理共享数据时,适当的锁定使volatile变得不必要,甚至可能有害。

volatile存储类最初是为了内存映射的I/O寄存器而设计的。在内核中,寄存器访问也应该受到锁的保护,但是我们也不希望编译器在临界区内对寄存器访问进行"优化"。但是,在内核中,I/O内存访问总是通过访问器函数进行的;直接通过指针访问I/O内存是不被赞同的,并且在所有体系结构上都不起作用。这些访问器被编写为防止不希望的优化,因此,再次强调,volatile是不必要的。

还有一种情况可能会诱使人们使用volatile,那就是处理器正在忙等待变量的值。执行忙等待的正确方法是:

while (my_variable != what_i_want)
cpu_relax();

cpu_relax()调用可以降低CPU功耗或让出给超线程的双处理器;它也恰好作为编译器屏障,因此再次强调,volatile是不必要的。当然,忙等待通常是一种不友好的行为。

在内核中,仍然有一些罕见的情况下,volatile是有意义的:

  • 上述的访问器函数在直接I/O内存访问有效的体系结构上可能使用volatile。实质上,每个访问器调用本身就成为一个小的临界区,并确保访问按照程序员的预期进行。
  • 内联汇编代码会更改内存,但没有其他可见的副作用,这可能会被GCC删除。在asm语句中添加volatile关键字将防止此删除。
  • jiffies变量是特殊的,因为每次引用它时它的值可能不同,但可以在没有特殊锁定的情况下读取。因此,jiffies可以是volatile的,但强烈不建议添加其他此类变量。在这方面,jiffies被认为是一个"愚蠢的遗留问题"(Linus的话);修复它将比它值得的麻烦多。
  • 可能会被I/O设备修改的一致内存中的数据结构指针有时可能是volatile的。网络适配器使用的环形缓冲区,其中适配器更改指示已处理哪些描述符的指针,就是这种情况的一个例子。

对于大多数代码,上述关于volatile的理由都不适用。因此,使用volatile很可能被视为一个bug,并将对代码带来额外的审查。被诱惑使用volatile的开发人员应该退一步,思考他们真正想要实现什么。

通常欢迎删除volatile变量的补丁 - 只要它们附带了合理的理由,表明并发问题已经经过适当的思考。

相关文章
|
6月前
|
供应链
chatGPT提示词(for创新创业类竞赛 零基础
chatGPT提示词(for创新创业类竞赛 零基础
70 0
|
机器学习/深度学习 存储 人工智能
DeepSpeed ZeRO++:降低4倍网络通信,显著提高大模型及类ChatGPT模型训练效率
DeepSpeed ZeRO++:降低4倍网络通信,显著提高大模型及类ChatGPT模型训练效率
346 0
DeepSpeed ZeRO++:降低4倍网络通信,显著提高大模型及类ChatGPT模型训练效率
|
1月前
|
机器学习/深度学习 人工智能 并行计算
DeepSpeed Chat: 一键式RLHF训练,让你的类ChatGPT千亿大模型提速省钱15倍
DeepSpeed Chat 是一款革命性的平台,专为简化和加速类ChatGPT模型的训练而设计。通过一键式脚本,用户可以轻松完成从预训练模型到生成自定义ChatGPT模型的全过程。该系统复刻了InstructGPT的RLHF训练方法,并集成了一系列优化技术,如DeepSpeed Hybrid Engine,大幅提升了训练效率和经济性。使用DeepSpeed Chat,即使是拥有数千亿参数的大模型,也能在短时间内完成训练,且成本显著降低。无论是单GPU还是多GPU集群环境,DeepSpeed Chat都能提供卓越的性能和易用性,让RLHF训练变得更加普及。
DeepSpeed Chat: 一键式RLHF训练,让你的类ChatGPT千亿大模型提速省钱15倍
|
2月前
总线类型 【ChatGPT】
总线类型 【ChatGPT】
|
3月前
Claude——如何在国内就体验类chatGPT
Claude——如何在国内就体验类chatGPT
58 2
|
2月前
|
安全 编译器 测试技术
锁类型及其规则 【ChatGPT】
锁类型及其规则 【ChatGPT】
|
4月前
|
自然语言处理 前端开发 JavaScript
【动画进阶】类 ChatGpt 多行文本打字效果
好了,本文到此结束,希望本文对你有所帮助 😃 想 Get 到最有意思的 CSS 资讯,千万不要错过我的公众号 -- iCSS前端趣闻 😄 更多精彩 CSS 技术文章汇总在我的 Github -- iCSS ,持续更新,欢迎点个 star 订阅收藏。 如果还有什么疑问或者建议,可以多多交流,原创文章,文笔有限,才疏学浅,文中若有不正之处,万望告知。 想 Get 到最有意思的 CSS 资讯,千万不要错过我的 iCSS 公众号 😄 :
39 0
|
6月前
|
人工智能 测试技术 开发者
马斯克将在本周,开源类ChatGPT产品Grok
【2月更文挑战第21天】马斯克将在本周,开源类ChatGPT产品Grok
80 1
马斯克将在本周,开源类ChatGPT产品Grok
|
人工智能 自然语言处理 运维
复旦发布国内首个类ChatGPT模型MOSS,和《流浪地球》有关?
复旦发布国内首个类ChatGPT模型MOSS,和《流浪地球》有关?
111 0
|
机器学习/深度学习 人工智能 缓存
DeepSpeed Chat: 一键式RLHF训练,让你的类ChatGPT千亿大模型提速省钱15倍
DeepSpeed Chat: 一键式RLHF训练,让你的类ChatGPT千亿大模型提速省钱15倍
DeepSpeed Chat: 一键式RLHF训练,让你的类ChatGPT千亿大模型提速省钱15倍