对于单个缓存行,单侧 RDMA 读取是原子的吗?
Are one-sided RDMA reads atomic for single cache lines?
我的小组(一个名为 Isis2 的项目)正在试验 RDMA。我们对缺乏单边 RDMA 读取的原子性保证的文档感到困惑。在过去的一个半小时里,我一直在寻找与此相关的任何信息,但都无济于事。这包括仔细阅读 rdmamojo.com 上的博客,该博客以对每个 RDMA 问题都有答案而闻名...
在我们关注的情况下,我们希望编写器对始终适合单个缓存行的对象执行原子写入。假设这发生在机器 A 上。然后我们计划在机器 B 上有一个单侧原子 RDMA reader,它可能会从 A 读取内存块,跨越许多这些对象(但同样,永远不会有对象以非原子方式编写,并且所有内容都将适合某个单个缓存行)。所以 B 读取 X、Y 和 Z,这些对象中的每一个都存在于 A 上的一个缓存行中,并且是用原子写入写入的。
因此,原子写入将在本地进行,但 RDMA 读取将从远程机器到达,并且在没有本地 CPU 参与的情况下完成。
我们的单边读取 "semantically equivalent" 是否是原子本地读取,尽管是在远程机器上启动的? (我怀疑是这样:否则,单侧 RDMA 读取对于曾经修改过的数据将毫无用处......)。 "rules" 记录在哪里?
我不知道有任何这样的原子性保证。当然 RDMA 读取是由远程适配器执行的,缓存行大小是一个 CPU 的概念。我不相信有什么能确保远程 RDMA 适配器使用的读取粒度与远程 CPU.
执行的写入大小相匹配
实际上它可能会起作用,因为远程适配器可能会发出单个 PCI 事务等。但我认为没有任何架构可以保证您不会获得 "torn" 数据。
好的,同时我似乎找到了正确的答案,我认为罗兰的回答不太正确——部分正确但不完全正确。
在 http://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-manual-325462.pdf 中,这是 Intel 架构手册(我需要再次检查 AMD...)我发现了这个: Intel 64 和 IA 中的原子内存操作- 32 架构只保证内存操作数的一个子集
大小和对齐场景。保证原子操作的列表在 IA-32 的第 8.1.1 节中描述
英特尔® 架构软件开发人员手册,第 3A 卷。
然后在标题为 MULTIPLE-PROCESSOR 管理的部分中,可以找到很多关于保证原子操作的信息(第 2210 页)。特别是,英特尔保证其内存子系统对于本机类型(位、字节、各种大小的整数、浮点数)是原子的。这些 objects 必须对齐以适应高速缓存行(在当前 Intel 平台上为 64 字节),而不是跨越高速缓存行边界。但是英特尔保证无论什么设备正在使用内存总线,存储和获取都是原子的。
对于更复杂的 objects,如果您想确保安全执行,则需要锁定。此外,如果您正在进行多核操作,则必须使用英特尔指令的锁定(原子)变体来确保并发写入的一致性。对于在 C++ 或 C# 中标记为 volatile 的变量(Java 也是如此?),您会自动获得此信息。
总而言之,对本机类型的本地写入可以安全地与远程启动的 RDMA 读取配对。
但请注意字符串、字节数组——它们不是原子的,因为它们很容易跨越缓存行。此外,对具有多个数据字段的复杂 objects 的操作可能不是原子的——对于这样的事情,您需要一种更复杂的方法,例如 MSR 的 FaRM 论文(快速远程内存)中的方法。我自己的需求更简单,不需要 FaRM 实现的复杂版本编号方案...
PCIe 控制器中实现的缓存一致性协议应保证单个缓存行 RDMA 读取的原子性。在将数据返回到 RDMA 适配器之前,PCIe 控制器必须侦听 CPU 个内核的缓存并取得缓存行 (RFO) 的所有权。所以它应该看到缓存行的一些快照。
我的小组(一个名为 Isis2 的项目)正在试验 RDMA。我们对缺乏单边 RDMA 读取的原子性保证的文档感到困惑。在过去的一个半小时里,我一直在寻找与此相关的任何信息,但都无济于事。这包括仔细阅读 rdmamojo.com 上的博客,该博客以对每个 RDMA 问题都有答案而闻名...
在我们关注的情况下,我们希望编写器对始终适合单个缓存行的对象执行原子写入。假设这发生在机器 A 上。然后我们计划在机器 B 上有一个单侧原子 RDMA reader,它可能会从 A 读取内存块,跨越许多这些对象(但同样,永远不会有对象以非原子方式编写,并且所有内容都将适合某个单个缓存行)。所以 B 读取 X、Y 和 Z,这些对象中的每一个都存在于 A 上的一个缓存行中,并且是用原子写入写入的。
因此,原子写入将在本地进行,但 RDMA 读取将从远程机器到达,并且在没有本地 CPU 参与的情况下完成。
我们的单边读取 "semantically equivalent" 是否是原子本地读取,尽管是在远程机器上启动的? (我怀疑是这样:否则,单侧 RDMA 读取对于曾经修改过的数据将毫无用处......)。 "rules" 记录在哪里?
我不知道有任何这样的原子性保证。当然 RDMA 读取是由远程适配器执行的,缓存行大小是一个 CPU 的概念。我不相信有什么能确保远程 RDMA 适配器使用的读取粒度与远程 CPU.
执行的写入大小相匹配实际上它可能会起作用,因为远程适配器可能会发出单个 PCI 事务等。但我认为没有任何架构可以保证您不会获得 "torn" 数据。
好的,同时我似乎找到了正确的答案,我认为罗兰的回答不太正确——部分正确但不完全正确。
在 http://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-manual-325462.pdf 中,这是 Intel 架构手册(我需要再次检查 AMD...)我发现了这个: Intel 64 和 IA 中的原子内存操作- 32 架构只保证内存操作数的一个子集 大小和对齐场景。保证原子操作的列表在 IA-32 的第 8.1.1 节中描述 英特尔® 架构软件开发人员手册,第 3A 卷。
然后在标题为 MULTIPLE-PROCESSOR 管理的部分中,可以找到很多关于保证原子操作的信息(第 2210 页)。特别是,英特尔保证其内存子系统对于本机类型(位、字节、各种大小的整数、浮点数)是原子的。这些 objects 必须对齐以适应高速缓存行(在当前 Intel 平台上为 64 字节),而不是跨越高速缓存行边界。但是英特尔保证无论什么设备正在使用内存总线,存储和获取都是原子的。
对于更复杂的 objects,如果您想确保安全执行,则需要锁定。此外,如果您正在进行多核操作,则必须使用英特尔指令的锁定(原子)变体来确保并发写入的一致性。对于在 C++ 或 C# 中标记为 volatile 的变量(Java 也是如此?),您会自动获得此信息。
总而言之,对本机类型的本地写入可以安全地与远程启动的 RDMA 读取配对。
但请注意字符串、字节数组——它们不是原子的,因为它们很容易跨越缓存行。此外,对具有多个数据字段的复杂 objects 的操作可能不是原子的——对于这样的事情,您需要一种更复杂的方法,例如 MSR 的 FaRM 论文(快速远程内存)中的方法。我自己的需求更简单,不需要 FaRM 实现的复杂版本编号方案...
PCIe 控制器中实现的缓存一致性协议应保证单个缓存行 RDMA 读取的原子性。在将数据返回到 RDMA 适配器之前,PCIe 控制器必须侦听 CPU 个内核的缓存并取得缓存行 (RFO) 的所有权。所以它应该看到缓存行的一些快照。