C#如何保证读/写操作的原子性?

zne*_*eak 9 c# atomic

在第5.5节,其读取和对某些类型的写入C#规格状态(即bool,char,byte,sbyte,short,ushort,uint,int,float,和引用类型)被保证是原子.

这激起了我的兴趣.你怎么能这样做?我的意思是,如果我希望读取和写入看起来是原子的,那么我个人的低级体验只能让我锁定变量或使用障碍; 如果必须为每一次读/写操作完成,那将是一个性能杀手.然而,C#做了类似的效果.

也许其他语言(如Java)可以做到这一点.我真的不知道.我的问题并不是特定于语言,只是我知道C#做到了.

我知道它可能必须处理某些特定的处理器指令,并且可能无法在C/C++中使用.但是,我仍然想知道它是如何工作的.

[编辑]说实话,我相信读取和写入在某些条件下可能是非原子的,就像CPU可以访问内存位置而另一个CPU在那里写入.这是否只会在CPU无法一次处理所有对象时发生,例如因为它太大或者内存未在正确的边界上对齐?

Jos*_*osh 15

这些类型保证原子性的原因是因为它们都是32位或更小.由于.NET仅在32位和64位操作系统上运行,因此处理器体系结构可以在单个操作中读取和写入整个值.这与32位平台上的Int64形成对比,后者必须使用两个32位操作进行读写.

我不是一个硬件家伙所以我道歉,如果我的术语让我听起来像一个小丑,但这是基本的想法.


Han*_*ant 5

在x86和x64内核上实现原子性保证相当便宜,因为CLR只承诺32位或更小的变量的原子性.所需要的只是变量正确对齐并且不跨越高速缓存行.JIT编译器通过在4字节对齐的堆栈偏移上分配局部变量来确保这一点.GC堆管理器对堆分配执行相同的操作.

值得注意的是CLR保证不是很好.对齐承诺不足以编写对双精度数组一致的代码.在这个帖子中很好地展示了.因此,与使用SIMD指令的机器代码互操作也非常困难.