C 如何提高多线程读取文件的性能?

C 如何提高多线程读取文件的性能?,c,linux,unix,C,Linux,Unix,我需要在Linux下使用多线程读取单个文件。 只有读取操作,不需要写入。 文件读取不需要每次都读取整个文件。 它需要每次读取文件的一个或多个部分。 我预先存储每个部分的偏移量。 文件太大,无法放入主内存 例如,许多用户希望读取这样的文件。 我使用线程或进程来读取文件以响应用户请求。 Linux下会发生什么? 所有读取操作都将排队吗? 操作系统会一个接一个地读取文件吗? 是否有可能改善此类行动的绩效 我正在尝试实现一个用于信息检索的简单倒排索引。 我把字典放在内存中,把列表放在文件中。 每个文件都

我需要在Linux下使用多线程读取单个文件。 只有读取操作,不需要写入。 文件读取不需要每次都读取整个文件。 它需要每次读取文件的一个或多个部分。 我预先存储每个部分的偏移量。 文件太大,无法放入主内存

例如,许多用户希望读取这样的文件。 我使用线程或进程来读取文件以响应用户请求。 Linux下会发生什么? 所有读取操作都将排队吗? 操作系统会一个接一个地读取文件吗? 是否有可能改善此类行动的绩效


我正在尝试实现一个用于信息检索的简单倒排索引。 我把字典放在内存中,把列表放在文件中。 每个文件都包含一段索引。 在字典中,我可以存储类似偏移量的内容,以指向单词的发布列表的位置。 当100个用户想要在一秒钟内搜索某个内容时,他们会提交不同的查询。
因此,每次读取都会读取文件的不同部分。

尝试以尽可能简单的方式开始执行它-让操作系统通过缓存等方式提高效率。看看性能如何-它可能根本不是瓶颈。操作系统通常擅长这类事情:)


假设您能够多次打开文件进行共享读取,我希望它能够正常工作,而不会让所有读取操作排队。

操作系统通常非常擅长优化对文件的访问(Linux以积极缓存著称)但我认为,减少读取量对于提高效率至关重要,您真的不能用一个表示文件一部分的共享数据结构来逃避吗?通过这种方式,一个线程可以读取,而其他线程都可以从读取中获益。因为它只是读取,所以只有在填充数据结构时,数据结构上才应该没有任何争用。如果每个线程每次都读取文件的不同部分,那么这当然是不可行的


如果您既不能从缓存中获益(很多),也不能共享文件的读取部分,那么除了提高磁盘子系统的性能(RAID 10)之外,没有多少事情要做(只需读取文件)。如果这还不够,请在不同的逻辑驱动器上制作两个或多个文件副本,以便能够进一步提高吞吐量

线程都可以安全地独立读取文件,是的。最终,读取操作将在操作系统级别排队,因此驱动程序将读取请求序列化到磁盘。根据访问策略(即读取缓冲区大小),读取应该是交错的。除非您尝试在一个请求中读取整个文件(您不应该这样做,因为您说它太大,无法装入内存),否则读取请求将按照线程请求的顺序进行服务。(我说大概,因为磁盘驱动程序可以对队列中已知的读取请求重新排序,以优化磁盘访问)。所以你所描述的应该很好。而且操作系统将相当积极地尽可能多地缓存读取(和预加载)

至于提高性能,根据使用的数据和算法,有许多可能性。每个线程真的需要读取整个文件来服务每个请求吗?为什么反复阅读相同的数据?你不能集中一些信息以便线程可以共享读取的数据吗?这听起来像是一个昂贵的解决方案。如果您反复读取一个比RAM大的文件,那么最近缓存的块很有可能被重新读取,可能会被从缓存中推出。也许文件的索引可以为您节省一些读取时间,您是否可以基于索引缓存访问?还可以考虑使用<代码> MAMP()/<代码>将文件映射到内存中,然后OS将从不同块读取线程时输入和输出块。因此,有必要重新思考如何访问数据,需要什么以及何时访问。如果你在这里发布更多信息,人们可能会提供更具体的建议


记住,最有效的操作是你不执行的操作

您的文件有多大以至于无法全部放入内存

最有效的方法是将文件放入o/s,并使用
mmap()
将文件映射到(虚拟)内存中,然后让所有线程通过内存访问文件。如果你在一台32位的机器上,这将你的文件大小限制在“4GB以下,但可能远远超过2GB”;如果您使用的是64位计算机,那么除了磁盘空间之外,您并没有受到真正的限制


请注意,使用
mmap();但是,从逻辑上讲,它都会存在。

如果文件太大,无法放入系统内存,并且您有很多线程需要读取整个文件,那么您的应用程序很可能会受到磁盘I/O的限制。。。无论您如何读取文件,无论操作系统多么智能

如果这是不可接受的,那么您需要为您的应用程序提出一个替代体系结构。例如,您可以将文件转换为另一种形式,允许线程通过读取整个文件来获取所需的信息。或者,您可以将应用程序转换为运行在不同计算机上的独立进程,每个进程都有自己的文件副本。第三种可能是添加一个线程,其唯一目的是读取和缓冲文件,并从缓冲区读取现有线程。(通过让工作线程都在文件的同一区域上工作,可以避免操作系统多次从磁盘读取部分文件。如果应用程序确实是磁盘绑定的,这可能会加快速度。)

然而,所有这些都是猜测。没有mo,很难给出像样的建议