Eth*_* L. 4 linux x86 intel linux-device-driver
ENQCMD
和MOVDIR64B
是英特尔 DSA 中的两条指令。
MOVDIR64B
从源内存地址读取 64 字节,并对目标地址执行 64 字节直接存储操作。该ENQCMD
指令允许软件将命令写入队列寄存器,这些寄存器是使用内存映射 I/O (MMIO) 访问的特殊设备寄存器。
我的问题是——设计这两条指令的目的是什么?
根据我的理解,设置内存映射IO区域(寄存器)需要操作系统的支持,即设备驱动程序。设置MMIO区域后,我们可以使用write()
系统调用来访问它,这也是在设备驱动程序中实现的。对于一般架构,Linux 支持iowrite64()
一次写入 8 字节值。因此,如果我们要写入64字节,需要调用iowrite64()
8次。
在英特尔 DSA 的帮助下MOVDIR64B
,创建了一个新的 API__iowrite512()
-以原子方式写入 64 字节。
我同意后一种至少比前一种更有效,但我对传输数据所需的时间感到困惑。
考虑以下情况:如果给定一个支持MOVDIR64B
和 的设备(Intel DSA) ENQCMD
,假设我们想要将 64 字节数据从内存传输到 MMIO 寄存器。有两种选择:iowrite64()
8次(使用循环);或__iowrite512()
一次。后一个会比前一个快8倍吗?
我的想法是8倍差别的可能性较小,但后者会更快。我可以知道它会多快吗?它在任何地方都有记录吗?我没有 Intel DSA,所以我不知道如何测试它。
除此之外,还有什么好处呢ENQCMD
?会不会被分解成几个微操作?如果是的话,那么微操作有哪些作用呢ENQCMD
?
iowrite64 使用 UC 访问 MMIO 空间,因此写入是串行化的,而不是管道化的。也就是说,单个 CPU 线程一次只能进行一个 UC 写入,并且在 MMIO 写入完成之前 CPU 不会继续执行。
MOVDIR64B 有可能比单个 iowrite64 更快,因为它使用 WC 内存类型而不是 UC(即使目标地址是 UC)。CPU发出写操作后,就可以继续执行。多个直接存储可以流式传输到设备。这意味着单个 CPU 线程可以同时运行多个直接存储。MOVDIRI 也有这样的行为。
据我所知,无论大小(1 到 64 字节之间),实际将数据传输到目的地的时间都是相同的。当然,这取决于 SoC 内数据路径的宽度,对于不同的实现可能会有所不同。
MOVDIR64B 的主要优点是描述符一次全部到达设备而不是分段到达设备。设备不必担心接收部分描述符或接收两个交错描述符的部分。事实上,英特尔 DSA 会忽略对门户的小于 64 字节的写入。
为了充分发挥流写入的优势,单个 CPU 线程的每个 MOVDIR64B 的目标地址应该不同。每个英特尔 DSA 门户都是一个 4096 字节的页面,因此每个门户内有 64 个唯一地址。来自单个 CPU 的描述符写入可以跨 64 个地址进行条带化。(来自多个 CPU 的写入使用相同地址还是不同地址并不重要,但通常您不会期望多个 CPU 在 DSA 中使用相同的专用 WQ。)
ENQCMD 允许设备响应软件,无论它是否接受描述符。这允许多个应用程序使用相同的共享 WQ,而不会因为共享 WQ 已满而导致描述符丢失。应用程序可以提交描述符,无需任何驱动程序参与(设置后),并且应用程序之间无需任何锁定或通信。
归档时间: |
|
查看次数: |
894 次 |
最近记录: |