我想使用 DMA 来加速网络 I/O(密集的磁盘读取和通过 Internet 输出)。我想知道我是否有一个多线程应用程序,其中每个线程都发出 DMA 传输,操作系统如何安排磁盘 I/O 和 DMA 传输?
据我了解,内核在没有用户程序的情况下将所需的数据部分从磁盘加载到 RAM 并发出 DMA 传输。因此,磁盘调度程序不会有太大帮助(只有一个内核进程总是访问磁盘)。另外,我希望有任何内核设施可以在加载到内存中的数据时安排 DMA 传输吗?
最佳答案
网络驱动程序已经在使用 DMA 来加速传输。当您发出 write
时,内核将分配一个连续的物理内存块并将数据从您的用户空间缓冲区复制到该内存中。在此阶段,内核将附加所有必要的以太网和 TCP/IP header 。
然后内核将向网卡发出 DMA 请求,要求它从该物理内存位置获取数据并将其加载到其内部缓冲区中。此时您的write
系统调用将返回。当网卡完成时(数据正在离开适配器),网卡将向内核发出完成信号。
在 Linux 中,网络驱动程序通常是单线程的(这有一些异常(exception),但它变得复杂),所以如果您尝试写入
一些数据并且驱动程序已经处于事件状态,它仍然会被复制进入内核空间,但在网络驱动程序再次空闲之前不会执行 DMA 请求(它将在下一次通知内核 DMA 完成时触发)。
这个故事的士气是,这已经有效并且相当快,您不需要做任何事情来加速和使用 DMA 的应用程序,它已经得到处理。您唯一可以加速的部分是内核空间缓冲区中的副本,但由于这比实际的网络传输快得多(并且可以同时完成),它对吞吐量没有任何影响,只有延迟。
注意以上是一些地方的粗略简化,如果您想了解有关特定部分的更多详细信息,请编辑您的问题,我会尽力而为。
关于network-programming - 多线程应用程序中的直接内存访问 (DMA) 调度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9471728/