Assembly ARM指令ldrex/strex是否必须对缓存对齐的数据进行操作?

Assembly ARM指令ldrex/strex是否必须对缓存对齐的数据进行操作?,assembly,arm,lock-free,Assembly,Arm,Lock Free,在Intel上,CMPXCHG的参数必须与缓存线对齐(因为Intel使用MESI实现CAS) 在ARM上,ldrex和strex在granuales独家保留地运营 需要明确的是,这是否意味着在ARM上操作的数据不必与缓存线对齐?在ARM体系结构参考手册A.3.2.1“未对齐的数据访问”中有这样的说法LDREX和STREX需要单词对齐。这是有道理的,因为未对齐的数据访问可以跨越独占保留颗粒。独占访问限制 以下限制适用于独占访问: •具有给定ID的独占写入的大小和长度必须与 具有相同ID的先前独占读

在Intel上,CMPXCHG的参数必须与缓存线对齐(因为Intel使用MESI实现CAS)

在ARM上,ldrex和strex在granuales独家保留地运营


需要明确的是,这是否意味着在ARM上操作的数据不必与缓存线对齐?

在ARM体系结构参考手册A.3.2.1“未对齐的数据访问”中有这样的说法
LDREX
STREX
需要单词对齐。这是有道理的,因为未对齐的数据访问可以跨越独占保留颗粒。

独占访问限制

以下限制适用于独占访问:

•具有给定ID的独占写入的大小和长度必须与 具有相同ID的先前独占读取的大小和长度

•独占访问的地址必须与总字节数对齐 在交易中

•独占读取和独占写入的地址必须相同

•独占访问的读取部分的字段必须与AWID匹配 写入部分的

•专用访问的读写部分的控制信号必须 一模一样

•在独占访问突发中传输的字节数必须为幂 共2个字节,即1、2、4、8、16、32、64或128字节

•可在独占突发中传输的最大字节数为 128

•ARCACHE[3:0]或AWCACHE[3:0]信号的值必须保证 监视独占访问的从属服务器看到事务。对于 例如,由从属服务器监视的独占访问不得具有 ARCACHE[3:0]或AWCACHE[3:0]值,指示事务正在运行 可缓存

不遵守这些限制会导致不可预测的行为

以上内容来自AMBA/AXI规范。您会发现一些供应商忽略了AWLOCK/ARLOCK(这意味着ldrex/strex不会在核心之外工作)。我有一些代码演示了这一点,如果您发现一个系统不支持独占访问,至少会这样做


根据任务和您希望的可移植性,您可能需要提供由IFDEF包围的swp和ldrex/strex解决方案和/或使用大量可用寄存器(运行时)来告诉您正在运行的内核支持或不支持哪些指令。(至少在一种情况下,您可能会发现不支持swp或ldrex/strex)。

在英特尔上,CMPXCHG的参数不需要缓存对齐。试试看,你会发现它是有效的

但是,你是对的:在可缓存内存中,Intel确实使用缓存协议来实现CMPXCHG。因此,最好不要将两个独立的高使用率同步变量放在同一个缓存线中,因为如果两个处理器使用这些不同的变量进行同步,缓存线可能会来回摆动。但这与任何数据的问题完全相同:不允许不同的处理器同时写入同一缓存线。虚假分享

但您当然不能缓存行对齐锁:

struct Foo {
  int data;
  Lock lock;
  int data_after;
};
您可以在同一缓存线中放置不同的锁:

struct Foo {
  int data;
  Lock read_lock;
  int data_between;
  Lock write_lock;
  int data_after;
};
struct Foo {
  int data;
  Lock read_lock;
  int data_between;
  Lock write_lock;
  int data_after;
};
因为读和写往往是相互排斥的,所以可能不会有损失

您可以在同一缓存线中放置不同的锁:

struct Foo {
  int data;
  Lock read_lock;
  int data_between;
  Lock write_lock;
  int data_after;
};
struct Foo {
  int data;
  Lock read_lock;
  int data_between;
  Lock write_lock;
  int data_after;
};
顺便说一下,在非缓存内存中,Intel不使用缓存侦听协议进行CMPXCHG等原子操作。因此,缓存行对齐同步变量的理由较少。但您可能仍然希望:许多内存子系统按缓存线大小交错,即使在未缓存时也是如此

至于手臂:几乎是一样的

在snoopy总线或未缓存总线上,您可能不需要太担心缓存线对齐


但是在集群缓存层次结构中,您会遇到与x86完全相同的问题。更重要的是,事实上,众所周知,如何“导出”CMPXCHG之类的操作,而不是ARM ldrexd/strexd。

我读取的ERG长度在8到2048字节之间,是2的倍数。如果ERG长度是10字节,那么您将使用对齐访问跨越ERG边界。ERG长度不是2的倍数吗?字对齐和缓存线对齐是两种不同的方式在x86世界中,“字”是16位,两个字节。在arm中,“字”是32位的,所以字对齐意味着地址的两个lsbits是相同的zero@BlankXavierA.3.4.3说ERG大小是2的幂。有多个手臂,应该使用与家庭/核心最密切相关的手臂。还需要trm和amba/axi规范。首先搜索ldrex或strex(在arm或trm中),然后搜索“独占”或“共享”。