【问题标题】:Using interrupts during reading a file from disk在从磁盘读取文件时使用中断
【发布时间】:2013-11-23 15:45:13
【问题描述】:

假设一个大文件保存在磁盘上,我想对文件中包含的每个数据块进行计算。

我为此编写的 C/C++ 代码将加载文件的一部分,然后进行处理,然后加载下一部分,然后处理下一部分,依此类推。

但是,如果我有兴趣在尽可能短的时间内这样做,我实际上可以执行以下操作:首先,告诉 DMA 控制器加载文件的第一部分。当这部分被加载时,告诉 DMA 控制器加载第二部分(在内存的其他部分中),然后立即开始处理第一部分。

如果我在处理第一部分的过程中收到来自 DMA 的中断,我会完成第一部分,然后告诉 DMA 用文件的第三部分覆盖它;然后我处理第二部分。

如果我在处理第一部分的过程中没有收到来自 DMA 的中断,我会完成第一部分并等待 DMA 的中断。

根据处理与磁盘读取相关的时间,这应该快两倍。在现实中,当然,必须进行测量。但这不是我要问的问题。

问题是:是否有可能做到这一点 a) 在 C 中使用一些非标准扩展或 b) 在汇编中?或者操作系统通常不允许这样的事情?这个问题主要是在单线程上下文中,尽管我也有兴趣知道如何用两个线程来做。另外,我对特定代码感兴趣;这更像是一个理论问题。

【问题讨论】:

  • 这不是操作系统中管道的用途吗?
  • 对于用户态代码而言,您的级别太低了。不要忘记您的应用程序不是唯一运行的东西,并且磁盘控制器是共享的。通常,您实际上并不知道您的数据在磁盘上的位置。查看异步 I/O 和/或内存映射文件以及您的操作系统有哪些选项。
  • 任何重要的操作系统都已经可以这样工作了。非常不清楚你为什么认为你需要帮助。
  • 一个相当智能的操作系统会以这种方式在内部实现 mmap...
  • 重点是:如何确保计算机同时读取和处理。在编写 C 代码时,我认为操作系统必须停止进程,直到读取所有数据。也许管道是我一直在寻找的答案......

标签: c performance assembly operating-system dma


【解决方案1】:

您是对的,默认情况下您不会从中受益,因为阻塞读取会阻止您的线程进行任何处理。 Hans 是对的,现代操作系统已经处理了 DMA 和中断完成例程的所有小细节。

您需要使用您所描述的架构,即在您何时使用数据之前发出请求。发出异步 I/O 请求(在 Windows 上,这些请求称为 OVERLAPPED)。然后流程将完全按照您的设想进行,但 DMA 和中断在驱动程序中处理。

在 Windows 上,查看FILE_FLAG_OVERLAPPED(至CreateFile)和ReadFile(如果您喜欢事件)或ReadFileEx(如果您喜欢回调)。如果您不必以任何特定顺序处理数据,则将完成端口添加到混合中,它将完成响应排队。

在 Linux、OSX 和许多其他类 Unix 操作系统上,请查看 aio_read。或fadvise。或者使用mmapmadvise

您甚至无需编写本机代码即可获得这些好处。 .NET 最近在其FileStream 中添加了ReadAsync 方法,该方法可以与Task 对象形式的连续传递样式一起使用,与C# 编译器中的async/await 语法糖一起使用。

【讨论】:

    【解决方案2】:

    通常,在多模式(用户/系统)操作系统中,您无权访问直接 dma 或中断。在将这些功能从内核(系统)模式扩展到用户模式的系统中,开销消除了使用它们的好处。

    忽略您要求做的事情需要一个非常专业的环境来支持它,这个想法是合理且普遍的:声明两个(或更多)缓冲区以在处理第一个缓冲区时启用下一个 DMA。当使用两个缓冲区时,它们有时被称为乒乓缓冲区。

    【讨论】:

      猜你喜欢
      • 2014-11-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-14
      • 2014-10-08
      • 2023-03-13
      相关资源
      最近更新 更多