1

在我提出问题之前,我将回顾一下我目前正在使用的内容,以便您对我已经做过/尝试过的事情有一个不错的了解。

我有一个多线程用户模式 ​​Windows 桌面应用程序,它向 KMDF 驱动程序(纯软件,没有硬件)发出 DeviceIOControl 调用。有 5 个单独的线程不断地对驱动程序进行相同的自定义 IOCTL 调用。该请求包括:

  1. PsLookupProcessByProcessId 获取要从中读取内存的进程。
  2. MmCopyVirtualMemory 将请求的内存复制到提供的缓冲区中。
  3. ObDereferenceObject 减少引用计数。

驱动程序目前正在串行执行此操作,而我的用户模式应用程序的主要瓶颈是等待内存读取完成,并且在场景可以“渲染”之前一切都需要完成。

我已经尽可能地减少了 DeviceIOControl 请求的数量,所以现在我一直在研究重叠的 IO 并允许每个线程异步发送请求。我的问题是这是否值得尝试,因为我不知道是否可以在驱动程序中使用多个线程同时从不同地址读取。

4

2 回答 2

2

好的,看起来您问题中最重要的部分在这里:

我一直在广泛搜索,试图找出在 WDF 处理 IOCTL 请求的方式方面究竟打开一个重叠文件的实际变化 [...]

它不会改变任何东西;对设备驱动程序的所有请求都是异步的。

当您在同步句柄上执行 I/O 时,Windows 会代表您向驱动程序发出异步 I/O 请求并等待它完成。 据我所知,驱动程序甚至无法判断原始请求是同步的还是重叠的。 [编辑:这不是真的。正如 RbMm 在评论中指出的那样,内核实际上确实区分了同步和异步 I/O,但从实际的角度来看,这对你来说并不重要。]

无论如何,如果驱动程序当前仅在单个线程上运行,则使用重叠 I/O 将无济于事。您将不得不修改驱动程序。相反,修改驱动程序就足够了;您可能不需要更改应用程序。(例外:我不确定从多个线程同时使用相同的同步句柄是否合法,因此我建议每个线程打开自己的设备句柄,至少在您确定驱动程序正在工作之前如预期的。)

我不熟悉 WDF,但 MSDN 条目Dispatching Methods for I/O Requests看起来很相关。

于 2017-02-08T23:31:51.897 回答
2

一开始很重要,用户模式如何打开文件——同步还是异步模式?(FILE_FLAG_OVERLAPPEDCreateFileFILE_SYNCHRONOUS_IO_[NO]NALERTZwOpenFileZwCreateFile)

如果文件以同步模式打开(FO_SYNCHRONOUS_IO将在FILE_OBJECT.Flags)I/O 子系统将所有请求序列化到文件 - 所以在之前完成之前它不会向您的设备发送新请求。使用异步文件对象 - 没有这样的限制 - 请求(IRP)只会发送到您的设备

如果你这么说的话

然而,线程本身是相互独立的。

如果线程FILE_FLAG_OVERLAPPED共享一个文件句柄(FILE_OBJECT认为更好的共享异步文件。

从驱动程序方面,您必须使用WdfIoQueueDispatchParallel队列调度类型。所以只需请求(IRP)处理它并完成(我怎么理解你不将此请求发送给另一个驱动程序,或放入另一个队列)

基本上我要问的是,对于重叠的 IO,它是否相当于我的驱动程序的一个实例处理每个线程,或者它仍然是一个驱动程序从 5 个线程获得大量请求并努力跟上?

你总是有一个驱动程序实例和设备计数,你创建了多少个。如果您只创建一个设备 - 并且将只有这一个设备。所有文件都将在此设备上打开。所有请求(来自任何进程/线程)都将发送到这个单个设备实例。

如果您对所有线程使用相同的文件并且它将是同步文件 - I/O 子系统将所有请求序列化到驱动程序 - 这对您不利。您的驱动程序(设备)的客户端必须以异步方式打开文件(或每个客户端都打开自己的私有文件)。从驱动程序方面 - 您需要WdfIoQueueDispatchParallel队列调度类型,因为我如何理解所有请求都是独立的,并且您不需要请求之间的同步

于 2017-02-09T00:36:14.613 回答