C++ 中的原子性:神话还是现实 [英] Atomicity in C++ : Myth or Reality

查看:33
本文介绍了C++ 中的原子性:神话还是现实的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在阅读一篇关于无锁编程的文章在 MSDN 中.它说:

I have been reading an article about Lockless Programming in MSDN. It says :

在所有现代处理器上,您都可以假设读取和写入自然对齐的原生类型是原子的.只要内存总线是至少与类型一样宽读或写,CPU 读取和在单个总线中写入这些类型交易,使其无法其他线程以查看它们半完成状态.

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++ 编译器的东西?

I read lots of answers and comments saying, nothing is guaranteed to be atomic in C++ and it is not even mentioned in standarts, in SO and now I am a bit confused. Am I misinterpreting the article? Or does the article writer talk about things that are non-standart and specific to MSVC++ compiler?

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

So according to the article the below assignments must be atomic, right?

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 变量的赋值仍然是原子的吗?

If it is true, does replacing Name[5] and pad3[3] with std::string Name; make any difference in memory-alignment ? Will the assignments to Number2 and Value variables be still atomic?

谁能解释一下?

推荐答案

此建议是特定于体系结构的.x86 & 确实如此x86_64(在低级编程中).您还应该检查编译器是否不会重新排序您的代码.您可以使用编译器内存屏障"为此.

This recommendation is architecture-specific. It is true for x86 & x86_64 (in a low-level programming). You should also check that compiler don't reorder your code. You can use "compiler memory barrier" for that.

英特尔参考手册英特尔® 64 位和 IA-32 架构软件开发人员手册"中描述了 x86 的低级原子读写.第 3A 卷(http://www.intel.com/Assets/PDF/manual/253668.pdf) ,第 8.1.1 节

Low-level atomic read and writes for x86 is described in Intel Reference manuals "The Intel® 64 and IA-32 Architectures Software Developer’s Manual" Volume 3A ( http://www.intel.com/Assets/PDF/manual/253668.pdf) , section 8.1.1

8.1.1 保证原子操作

Intel486 处理器(以及后来的处理器)保证以下基本内存操作将始终以原子方式执行:

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 位访问
    • P6 系列处理器(以及之后的更新处理器)保证以下额外的内存操作将始终以原子方式执行:

      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 等较新处理器的原子性进行了更多描述.并非所有未对齐的操作都是原子操作.

        This document also have more description of atomically for newer processors like Core2. Not all unaligned operations will be atomic.

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

        Other intel manual recommends this white paper:

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

        这篇关于C++ 中的原子性:神话还是现实的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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