在Linux内核中读写原子操作实现 [英] Read and Write atomic operation implementation in the Linux Kernel

查看:474
本文介绍了在Linux内核中读写原子操作实现的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

最近,我偷看了原子读写的Linux内核实现,并提出了一些问题.

Recently I've peeked into the Linux kernel implementation of an atomic read and write and a few questions came up.

首先是ia64架构中的相关代码:

First the relevant code from the ia64 architecture:

typedef struct {
    int counter;
} atomic_t;

#define atomic_read(v)      (*(volatile int *)&(v)->counter)
#define atomic64_read(v)    (*(volatile long *)&(v)->counter)

#define atomic_set(v,i)     (((v)->counter) = (i))
#define atomic64_set(v,i)   (((v)->counter) = (i))

  1. 对于读取和写入操作,似乎都采用直接方法来读取或写入变量.除非某处有其他技巧,否则我不明白存在什么保证该操作在汇编域中是原子的.我猜很明显的答案是,这样的操作会转换为一个程序集操作码,但是即使如此,考虑到不同的内存缓存级别(或其他优化)又如何保证呢?

  1. For both read and write operations, it seems that the direct approach was taken to read from or write to the variable. Unless there is another trick somewhere, I do not understand what guarantees exist that this operation will be atomic in the assembly domain. I guess an obvious answer will be that such an operation translates to one assembly opcode, but even so, how is that guaranteed when taking into account the different memory cache levels (or other optimizations)?

在读取宏上,volatile类型用于强制转换技巧.任何人都知道这如何影响这里的原子性? (请注意,未在写入操作中使用它)

On the read macros, the volatile type is used in a casting trick. Anyone has a clue how this affects the atomicity here? (Note that it is not used in the write operation)

推荐答案

我认为您在这里误解了原子"和挥发"一词的用法(非常含糊).原子实际上仅表示原子将以原子方式读取或写入这些字(在一个步骤中,并保证此存储位置的内容始终是一次写入或另一次写入,而不是介于两者之间).并且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.

这篇关于在Linux内核中读写原子操作实现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆