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

查看:237
本文介绍了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 ++中没有任何东西可以保证是原子性的,甚至在标准语言中也没有提到,因此现在我有点困惑.我误解了这篇文章吗?还是文章作者谈论的是非标准的,特定于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;

如果为true,用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.

x86的低级原子读写在英特尔参考手册英特尔®64和IA-32体系结构软件开发人员手册"第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位边界上对齐的四字
    • 16位访问适合32位数据总线的未缓存内存位置
    • 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位对适合缓存的缓存的访问 线
        • Unaligned 16-, 32-, and 64-bit accesses to cached memory that fit within a cache line
        • 该文档还对像Core2这样的较新处理器进行了原子上的更多描述. 并非所有未对齐的操作都是原子操作.

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

          其他intel手册推荐此白皮书:

          Other intel manual recommends this white paper:

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

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

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