network-programming - 多线程应用程序中的直接内存访问 (DMA) 调度

标签 network-programming io linux-kernel linux-device-driver dma

我想使用 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/

相关文章:

c - 来自 C 中输入文件的垃圾值

linux-kernel - Linux内核 - 获取最后写入的内存块

c - 通过 TCP 传输数据总是停止在 251 传输

c++ - 在 Windows Phone 平台上选择返回 -1 的函数

c - 读取文件行,将每一行放入一个数组中,然后打印

各种数据类型的 Haskell IO 函数

linux - 如何列出被内核杀死的线程?

linux - 如何在中断处理程序中进行上下文切换?

javascript - 是什么导致 webrtc 数据通道消息出现这种 >1000 毫秒的滞后?

c - c中结构的定义