且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

在Linux内核中读写原子操作实现

更新时间:2023-09-24 10:50:34

我认为您在这里误解了原子"和挥发"一词的用法(非常含糊).原子实际上仅表示原子将以原子方式读取或写入这些字(在一个步骤中,并保证此存储位置的内容始终是一次写入或另一次写入,而不是介于两者之间).并且volatile关键字告诉编译器由于较早的读/写操作而从不假定该位置的数据(基本上,从不优化读取操作).

I think you are misunderstanding the (very much vague) usage of the word "atomic" and "volatile" here. Atomic only really means that the words will be read or written atomically (in one step, and guaranteeing that the contents of this memory position will always be one write or the other, and not something in between). And the volatile keyword tells the compiler to never assume the data in that location due to an earlier read/write (basically, never optimize away the read).

原子"和易失"这两个词在这里并不意味着存在任何形式的内存同步.两者均不暗示任何读/写障碍或篱笆.关于内存和缓存一致性,没有任何保证.这些功能基本上仅在软件级别上是原子性的,并且硬件可以根据自己的意愿对其进行优化/配置.

What the words "atomic" and "volatile" do NOT mean here is that there's any form of memory synchronization. Neither implies ANY read/write barriers or fences. Nothing is guaranteed with regards to memory and cache coherence. These functions are basically atomic only at the software level, and the hardware can optimize/lie however it deems fit.

现在为什么简单地读取就足够了:每种体系结构的内存模型都不同.许多体系结构可以保证对数据进行原子读取或写入,这些数据对齐到某个字节偏移或长度为x个字等,并且随CPU的不同而不同. Linux内核包含许多针对不同体系结构的定义,这些定义使它可以在保证(有时甚至只有在实践中,即使实际上他们的规范说实际上不能保证)原子的平台上进行任何原子调用(基本上是CMPXCHG)读/写.

Now as to why simply reading is enough: the memory models for each architecture are different. Many architectures can guarantee atomic reads or writes for data aligned to a certain byte offset, or x words in length, etc. and vary from CPU to CPU. The Linux kernel contains many defines for the different architectures that let it do without any atomic calls (CMPXCHG, basically) on platforms that guarantee (sometimes even only in practice even if in reality their spec says the don't actually guarantee) atomic reads/writes.

对于volatile,虽然通常不需要 ,除非您正在访问内存映射的IO,但这全都取决于atomic_read的时间/位置/原因和原因. atomic_write宏正在被调用.许多编译器会 (尽管在C规范中未设置)会为易失性变量生成内存屏障/栅栏(我心中最先想到的是GCC,MSVC肯定会这样做).虽然这通常 表示 all 对该变量的读/写现在几乎不受编译器优化的限制,但在这种情况下,仅创建虚拟"易失变量这种特定的读/写实例对于优化和重新排序是禁止的.

As for the volatile, while there is no need for it in general unless you're accessing memory-mapped IO, it all depends on when/where/why the atomic_read and atomic_write macros are being called. Many compilers will (though it is not set in the C spec) generate memory barriers/fences for volatile variables (GCC, off the top of my head, is one. MSVC does for sure.). While this would normally mean that all reads/writes to this variable are now officially exempt from just about any compiler optimizations, in this case by creating a "virtual" volatile variable only this particular instance of a read/write is off-limits for optimization and re-ordering.