在Linux内核中读写primefaces操作实现

最近我看到了primefaces读写的Linux内核实现,并提出了一些问题。

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

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. 对于读取和写入操作,似乎采用直接方法来读取或写入变量。 除非在某处有另一个技巧,否则我不明白这个操作在汇编域中是否具有primefaces性的保证。 我想一个明显的答案是,这样的操作转换为一个程序集操作码,但即便如此,在考虑不同的内存缓存级别(或其他优化)时,如何保证?

  2. 在读取宏上,volatile类型用于转换技巧。 任何人都知道这会如何影响这里的primefaces性? (注意,它不用于写操作)

我认为你误解了这里“primefaces”和“易变”这个词的含义(非常模糊)。 Atomic只是意味着单词将被primefaces地读取或写入(在一个步骤中,并保证该存储器位置的内容将始终是一个写入或另一个,而不是介于两者之间)。 并且volatile关键字告诉编译器由于较早的读/写而从不假设该位置中的数据(基本上,从不优化掉读取)。

“primefaces”和“易变”这两个词在这里并不意味着存在任何forms的内存同步。 两者都没有暗示任何读/写障碍或围栏。 关于内存和缓存一致性,没有任何保证。 这些function基本上只在软件级别是primefaces的,硬件可以优化/说谎,但它认为合适。

现在,为什么简单的阅读就足够了:每个架构的内存模型都不同。 许多体系结构可以保证对与某个字节偏移量对齐的数据进行primefaces读取或写入,或者长度为x个字等,并且因CPU而异。 Linux内核包含许多不同体系结构的定义,这些体系允许它在没有任何primefaces调用的情况下(基本上是CMPXCHG )在保证的平台上(有时甚至仅在实践中,即使实际上他们的规范说实际上并不保证)primefaces读取/写道。

至于volatile ,虽然除非你正在访问内存映射IO,否则一般不需要它,这一切都取决于何时/何地/为什么要调用atomic_readatomic_write宏。 许多编译器(虽然它没有在C规范中设置)为volatile变量生成内存屏障/栅栏(GCC,在我的头顶,是一个.MSVC肯定会这样做。)。 虽然这通常意味着对此变量的所有读/写现在都可以正式免除任何编译器优化,在这种情况下,通过创建“虚拟”volatile变量,只有这个特定的读/写实例才是优化的优化并重新订购。

读取在大多数主要体系结构上都是primefaces的,只要它们与其大小的倍数对齐(并且不大于给定类型的读取大小),请参阅英特尔体系结构手册。 另一方面,写入许多不同,英特尔声称在x86下,单字节写入和对齐写入可能是primefaces的,在IPF(IA64)下,一切都使用获取和释放语义,这将使其保证primefaces,请参阅此 。

volatile阻止编译器在本地缓存该值,从而强制它在有权访问它的地方进行检索。

如果您针对特定体系结构编写,则可以对其进行特定的假设。
我想IA-64确实将这些东西编译成一条指令。

缓存不应该是一个问题,除非计数器跨越缓存行边界。 但如果需要4/8字节对齐,则不会发生这种情况。

当机器指令转换为两次存储器访问时,需要“真正的”primefaces指令。 这是增量(读取,增量,写入)或比较和交换的情况。

volatile会影响编译器可以执行的优化。
例如,它阻止编译器将多个读取转换为一个读取。
但是在机器指令级别上,它什么也没做。