char数组上的C++内存模型和竞争条件

NoS*_*tAl 5 c++ memory-model race-condition c++11

基本上我无法理解这一点:(来自Bjarne FAQ)

但是,大多数现代处理器不能读取或写入单个字符,它必须读取或写入整个单词,因此对c的赋值实际上是"读取包含c的单词,替换c部分,然后再将单词写回". '由于对b的赋值是相似的,所以即使线程没有(根据它们的源文本)共享数据,两个线程也有很多机会相互冲突!

那么char数组如何在元素之间没有3(7?)字节填充的情况下存在?

Jam*_*nze 8

我认为Bjarne对此有误,或者至少,他正在大大简化事情.大多数现代处理器 能够写一个字节的不先读一个完整的词,或者更确切地说,他们表现得"好像"这样的话.特别是,如果你有一个char array[2];和线程一个只访问array[0]和线程两只访问array[1] ,那么你(当两个线程变异值包括)没有需要任何额外的同步; 这是由标准保证的.如果硬件不直接允许,则编译器必须自己添加同步.

注意上面的"好像"是非常重要的.现代硬件通过高速缓存行而不是字节来访问主存储器.但它也有修改高速缓存行中单个字节的规定,因此在写回时,处理器内核不会修改其缓存中未修改的字节.


Ker*_* SB 6

支持C++ 11的平台必须能够访问大小为1的存储char而不会发明写入.x86确实具备这种能力.如果处理器必须在任何时候一次修改32位,则它必须具有32位宽char.

(一些背景推理:数组是连续存储的,而字符没有填充(3.9.1).)

  • @NoSenseEtAl Ram-bus的功能和CPU的逻辑工作之间存在差异.而Stroustrup知道(并期望他的读者获得这些知识).x86-Assembler可以轻松访问字节.但是Ram-Interface会读取和写入整个32位(或64位)字. (2认同)