我们可以使用x86_64 CPU原子在PCI Express上生成复合原子操作吗?

时间:2017-05-29 19:38:44

标签: multithreading driver linux-device-driver x86-64 pci-e

  1. 如您所知,从版本2.0开始,PCI Express支持复合原子操作:FetchAddSwapCAShttps://pcisig.com/sites/default/files/specification_documents/ECN_Atomic_Ops_080417.pdf

    < / LI>
  2. 也知道,x86_64 CPU具有汇编程序复合原子操作:lock add[lock] xchglock cmpxchghttps://godbolt.org/g/MmqMRw

  3. 这可以由使用volatile atomic_int的C编译器生成 - 操作:

    int expceted_cas = 0;
    volatile atomic_int a;
    
    atomic_fetch_add( &a, 1 );
    atomic_exchange( &a, 1 );
    atomic_compare_exchange_weak( &a, &expceted_cas, 1 );
    

    我希望通过使用复合原子操作 访问通过PCI Express连接到PC-x86_64的设备上的缓冲存储器(以太网,GPU ......) >。即我们已经知道硬件总线是如何工作的(PCIe支持原子FetchAdd / Swap / CAS),但我们想知道需要什么汇编源代码来使用这个PCIe功能。

    我们可以使用x86_64 CPU复合原子操作:lock add[lock] xchglock cmpxchg在PCI Express上生成复合原子操作:FetchAddSwapCAS

    或者我们应该在x86_64 CPU上使用什么asm-code来在PCI Express 2.0 / 3.0上执行原子操作FetchAddSwapCAS

1 个答案:

答案 0 :(得分:3)

我可以从互联网上收集到的最新一代英特尔CPU在编写 [1] [2] [3] 仅支持PCIe AtomicOps Completers

集成到uncore中的PCIe设备可以完成AtomicOp但不能请求一个,PCIe端口可以请求AtomicOp,但这可能仅用于转发设备发起的请求。

似乎PCI根联合体无法请求AtomicOps 启用AtomicOps需要处理器和根联合体之间的紧密耦合:不仅处理器必须传输它正在执行的操作类型 - 从而实现x86指令和PCIe AtomicOps之间的映射 - 以及它的操作数。
此外,根联合体必须能够识别何时写入针对所有可能目的地中的启用AtomicOps的设备 - 因此需要一组软件可配置的地址范围。 最后,AtomicOps需要由QPI Quiesce Master专门处理 - 由于目标设备已经在处理原子性,因此可以避免全局QPI锁定。
所有这一切,当然,假设目标内存不可缓存(或者将发生缓存锁定)。

我不认为这些是不可逾越的障碍,而是我认为AtomicOps的发明主要是为了缩短IO-> HostMem原子写入或IO-> IO写入的延迟。
Looking at what Intel wrote

  

今天,基于消息的事务用于PCIe设备,并且这些事务使用可能经历长延迟的中断,这与使用原子事务的主内存的CPU更新不同。

似乎主要关注的是使用中断来通知设备驱动程序必须代表其受管设备执行原子写入。

Host-&gt; IO AtomicOps是允许的,但似乎它们不能像今天那样生成, 肯定不是单独使用lock前缀 我还认为,从处理器向设备发出AtomicOps仅对执行与其他PCIe设备相关的原子写入非常有用,因为处理器通常会与锁同步。