【发布时间】:2020-05-26 21:28:10
【问题描述】:
对于如何从软件进程的角度实现从针对常规内存的 PCIe 设备的卡主机写入,是否有任何保证,其中单个 TLP 写入完全包含在单个 CPU 高速缓存行中?
我想知道我的设备可能会写入一些数据字,后跟一个字节以指示结构现在有效(例如事件完成),例如:
struct PCIE_COMPLETION_T {
uint64_t data_a;
uint64_t data_b;
uint64_t data_c;
uint64_t data_d;
uint8_t valid;
} alignas(SYSTEM_CACHE_LINE_SIZE);
我是否可以使用单个 TLP 来编写此结构,这样当软件看到有效成员变为 1(之前已被软件清零)时,其他数据成员也会反映我拥有的值写入而不是以前的值?
目前我正在执行 2 次写入,首先写入数据,然后将其标记为有效,这没有任何明显的竞争条件,但当然会增加不必要的开销。
我在这个网站上看到的最相关的问题似乎是Are writes on the PCIe bus atomic?,尽管这似乎与 TLP 的相对顺序有关。
仔细阅读 PCIe 3.0 规范,我没有发现任何似乎明确涵盖了我的担忧的内容,我认为我并不特别需要 AtomicOps。鉴于我只关心与 x86-64 系统的交互,因此我还研究了英特尔架构指南,但也没有更清楚。
本能地,似乎应该有可能以原子方式感知这样的写入——尤其是当它被称为事务时——但同样,我在明确确认该观点的文档方式中找不到太多(我也不太确定我需要看什么,可能是 CPU 供应商?)。我还想知道这样的方案是否可以扩展到多个缓存线——即,如果有效位于从同一个 TLP 事务写入的第二个缓存线上,我可以确保第一个将不迟于第二个被感知吗?
【问题讨论】:
-
您不一定需要保证原子性,只需发布排序以与获取负载同步。即某种保证最后一个字节最后或同时可见,而不是之前。我标记了这个
[memory-order],不幸的是它是[memory-barriers]的标记同义词。我不知道您的实际问题的答案:/ -
谢谢,这似乎是合理的——我没有考虑过那个标签。
标签: x86-64 atomic memory-barriers pci-e