2013-11-21 42 views
1

是否有我可以读取,修改或默认比较原子的类型? 或者我应该为所有操作显式使用所有类型的原子操作?原子指令和原子类型

+0

@Damon我认为你应该把它作为答案 – Slava

+0

'std :: atomic '是一种你总是自动读取和修改的类型(准确地说,转换为'T'自动执行原子加载,并从'T'执行一个原子存储)。我不确定你的意思是“比较原子”。 –

回答

1

是的,你应该总是如果你需要原子性,使用原子类型或原子操作。没有什么不同。

形式上,没有非原子类型默认提供任何类型的原子访问。实际上,对于当前的CPU,任何内置类型都可以以原子方式读取和写入(但不能修改)。但是,这不是你有保证的东西,绝对不是你应该依赖的东西。这仅仅是一个实现细节。
当前CPU上的所有读取和写入均通过缓存。只有完整的缓存行(通常大约64-128字节)可以从主内存中读取或写回,并且缓存行是最大内置类型大小的倍数。这意味着如果一个类型正确对齐,它必然包含在单个缓存行中,这会自动使其读写成原子。但是,修改值是一个读取 - 修改 - 写入操作,这意味着即使每个步骤都是原子的,整个操作不是。

有不只是能够读取原子(或修改)的值更原子性,例如有您可能需要正确排序保证。即使读取和写入是原子性的,如果不按照预期的顺序通过不同的处理器看到修改,代码将无法正常工作。编译器和CPU(在一些合理的限制内)允许重新排序指令,包括加载和存储。但是,这可能意味着您的代码无法正确执行。因此

原子操作有一个“内存模型”与他们有联系,它允许你提供什么的之前发生,保证你的线程之间和相关或不相关的数据之间需要更多的信息。请参阅GCC Wiki以了解每种模式的详细说明。
默认情况下,原子操作选择顺序一致模式,这是最严格的限制是最安全的模式。如果你知道你不需要某些保证,你可以选择一个不同的模型,这可能(或者可能不会),这取决于体系结构)会导致生成更高性能的代码。
与内存模式的好处是,他们抽象的实现细节,建筑pecularities和成decribes你的算法要求,并保证这些要求得到满足形式编译巫术。

通常情况下,编译器就可以正常使用非原子机器指令,仍然保证您的要求得到满足(这可能会失去一个或另一个重新排序)。这取决于目标硬件如何工作的实际细节以及您需要什么保证。
总而言之,利用原子能和内存模型不仅更加舒适,而且不太容易出现故障的不是与手动的低电平(内联汇编)搞坏,也可能是最高效的方式成为可能。