从磁盘读取文件时使用中断

时间:2013-11-23 15:45:13

标签: c performance assembly operating-system dma

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

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

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

如果在处理第一部分期间从DMA获得中断,我完成第一部分,然后告诉DMA用文件的第三部分覆盖它;然后我处理第二部分。

如果在处理第一部分期间没有从DMA获得中断,我完成第一部分并等待DMA的中断。

根据处理相对于磁盘读取的时间长短,这应该高达两倍。实际上,当然,人们必须衡量。但这不是我要问的问题。

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

2 个答案:

答案 0 :(得分:1)

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

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

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

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

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

答案 1 :(得分:0)

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

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