正如我们所知,INTEL X86体系结构中与访问对齐的基本数据类型是原子的。ARMV8怎么样我试图从Arm架构参考手册Armv8中获得结果,对于A概要架构,我确实发现了一些与原子性有关的东西。ARMV8是另一个多拷贝原子。它承诺多线程访问同一个LOCATION是原子的。但它说LOCATION是一个字节。我想知道,如果线程1在没有锁的情况下写入对齐的uint64_t内存,而线程2同时在没有锁定的情况下读取或写入它。它是原子的吗?(uint64_t是8个字节,但LOCATION只有一个字节(
这在《ARMv8体系结构参考手册》B2.2中有解释。通常,高达64位的普通加载和存储(如果自然对齐(是单拷贝原子。特别是,如果一个线程存储到一个地址,而另一个线程加载相同的地址,则保证加载可以看到旧值或新值,而不会出现撕裂或其他未定义的行为。这大致类似于C或C++中的CCD_ 1加载或存储;实际上,您可以看到编译器为这种原子访问发出普通的加载和存储指令。https://godbolt.org/z/cWjaed9rM
让我们用一个例子来证明这一点。为了简单起见,让我们使用一个对齐的2字节半字H,调用其字节H0和H1。假设在遥远的过去,H被存储指令Wi初始化为0x0000;对字节H0和H1的相应写入将被表示为Wi.0和Wi.1。现在,让新的存储指令Wn={Wn.0,Wn.1}存储值0xFFFF,并让它与加载指令R={R.0,R.1}竞争。每个访问Wi,Wn,R都是B2.21的单拷贝原子,前两个项目符号。我们希望表明R.0和R.1都返回0x00,否则它们都返回0xFF。
通过B2.3.2,存在从读取的关系,将每个读取与一些写入配对。R.0必须从Wi.0或Wn.0读取,因为这是对H0仅有的两次写入,因此它必须返回0x00或0xFF。同样,R.1也必须返回0x00或0xFF。如果它们都返回0x00,我们就完成了,所以假设其中一个,比如R.1,返回0xFF,让我们展示R.0也返回0xFF。
我们假设R.1从Wn.1读取。通过B2.2.2(2(,无在B2.3.2的意义上,Wn生成的重叠写入在R生成的相应重叠读取之后是一致性。特别是,Wn.0在R.0之后不是连贯性。
请注意,Wn.0是Wi.0之后的一致性(连贯性顺序是写入的总顺序,因此一个必须在另一个之后,我们假设Wi发生在很久以前,其间有足够的排序或同步(。因此,如果R.0从Wi.0中读取,则Wn.0是R.0之后的连贯性(之后一致性的定义,第二句(。我们只是认为事实并非如此,所以R.0不会从Wi.0读取;它必须从Wn.0读取,因此返回0xFF
请注意,在x86上,普通加载和存储分别隐含着获取和发布顺序,而在ARM64上则不然。为此,您必须使用ldar / stlr
。