c++ - C++ 中的原子性 : Myth or Reality

标签 c++ atomic memory-alignment

我一直在阅读一篇关于 Lockless Programming 的文章在 MSDN 中。它说:

On all modern processors, you can assume that reads and writes of naturally aligned native types are atomic. As long as the memory bus is at least as wide as the type being read or written, the CPU reads and writes these types in a single bus transaction, making it impossible for other threads to see them in a half-completed state.

它给出了一些例子:

// This write is not atomic because it is not natively aligned.
DWORD* pData = (DWORD*)(pChar + 1);
*pData = 0;

// This is not atomic because it is three separate operations.
++g_globalCounter;

// This write is atomic.
g_alignedGlobal = 0;

// This read is atomic.
DWORD local = g_alignedGlobal;

我读了很多答案和评论说,在 C++ 中没有任何东西可以保证是原子的,甚至在标准中都没有提到,在 SO 中,现在我有点困惑。我误解了这篇文章吗?或者文章作者是否谈论了非标准的和特定于 MSVC++ 编译器的东西?

所以根据文章,下面的赋值必须是原子的,对吧?

struct Data
{
    char ID;
    char pad1[3];
    short Number;
    char pad2[2];
    char Name[5];
    char pad3[3];
    int Number2;
    double Value;
} DataVal;

DataVal.ID = 0;
DataVal.Number = 1000;
DataVal.Number2 = 0xFFFFFF;
DataVal.Value = 1.2;

如果是真的,用 std::string Name; 替换 Name[5]pad3[3] 有什么不同吗在内存对齐? Number2Value 变量的赋值仍然是原子的吗?

谁能解释一下?

最佳答案

此建议是特定于架构的。对于 x86 和 x86_64(在低级编程中)也是如此。您还应该检查编译器不会重新排序您的代码。您可以为此使用“编译器内存屏障”。

英特尔引用手册“英特尔® 64 和 IA-32 架构软件开发人员手册”第 3A 卷 (http://www.intel.com/Assets/PDF/manual/253668.pdf) 的第 8.1.1 节介绍了 x86 的低级原子读取和写入

8.1.1 Guaranteed Atomic Operations

The Intel486 processor (and newer processors since) guarantees that the following basic memory operations will always be carried out atomically:

  • 读取或写入一个字节
  • 读取或写入在 16 位边界上对齐的字
  • 读取或写入在 32 位边界上对齐的双字

The Pentium processor (and newer processors since) guarantees that the following additional memory operations will always be carried out atomically:

  • 读取或写入在 64 位边界上对齐的四字
  • 对适合 32 位数据总线的未缓存内存位置进行 16 位访问

The P6 family processors (and newer processors since) guarantee that the following additional memory operation will always be carried out atomically:

  • 对适合缓存的缓存内存进行未对齐的 16 位、32 位和 64 位访问 行

本文档还对 Core2 等较新的处理器进行了原子化的更多描述。 并非所有未对齐的操作都是原子的。

其他英特尔手册推荐此白皮书:

http://software.intel.com/en-us/articles/developing-multithreaded-applications-a-platform-consistent-approach/

关于c++ - C++ 中的原子性 : Myth or Reality,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5002046/

相关文章:

c++ - 为什么这个 EXC_BAD_ACCESS 发生在 long long 而不是 int 上?

C++ 处理 PPM 图像

c++ - 使用 unique_ptr 作为我自己的移动构造函数的替代方法是一种好习惯吗?

python - redis.pipeline() 的局限性

linux - 以原子方式移动目录

c++ - 为什么打包对象的 sizeof 低于预期?

c++ - C++ 的 Qt webkit 教程

c++ - 如何访问整个 map 的值

c++ - 将多个值打包成一个原子的标准化方法

c++ - 无法在循环中动态分配内存(一个函数吃掉所有内存)