我在RHEL 5.8上有一个多线程应用程序,它通过mmap读取大文件(每个大约500MB)并对它们进行一些处理;一个线程执行mmap,其他线程执行处理。当文件不再在文件系统上时,执行munmap以释放内存。 我的问题是munmap(有时关闭文件)减慢了其他线程,在不同的内存上执行操作,所以我想知道是否有更好的方法来实现它。我有2个想法:将内存拆分为较小的块来分配较小的块(这是否可能?),或者根本不使用munmap并自行分配/释放内存,如果文件不再在文件系统上,可选择缓存内存块,并将其重用于下一个文件。 谢谢你的任何想法。
答案 0 :(得分:1)
它变慢的实际原因是munmap()
在系统调用的整个持续时间内采用mm-> mmap_sem锁定。其他一些操作可能会受到阻止,例如(但不限于)fork()
/ mmap()
。对于没有对已经在内存中的页面实现无锁get_user_pages_fast()
操作的体系结构,这一点尤其重要,因为一堆futex操作(支持pthread原语)将调用get_user_pages_fast()
和默认实现将尝试对mmap_sem
进行读取锁定。
答案 1 :(得分:0)
如果您按顺序读取内存,请尝试在读取内存页面上定期使用posix_madvise()
和MADV_DONTNEED
。请参阅posix_madvise()。
它也可以在Linux下以madvise()
的形式使用。见madvise()
答案 2 :(得分:0)
当文件不再存在于文件系统上时,执行munmap
因此,当文件从文件系统取消链接时,请调用munmap
。然后,可能是什么减慢了系统的实际删除inode,这是在释放所有目录条目,文件描述符和内存映射时完成的。
在linux(ext3)的某些文件系统中存在删除性能的已知问题。如果是这种情况,您可以尝试更改为ext4(使用范围),如果在您的方案中这是可行的。
其他选项是硬链接其他目录中的文件,因此当您munmmap
时,它们不会被真正删除。然后,您可以调用ionice -c 3 rm <last-link>
或类似内容以在后台实际删除它们
答案 3 :(得分:0)
我最终做的事情(并且证明是足够的)是将大内存块分成几块,例如我有500MB块,我用100MB块执行munmap。