C语言中的malloc与mmap

kqlmhetl  于 2022-12-03  发布在  其他
关注(0)|答案(7)|浏览(363)

我构建了两个程序,一个使用malloc,另一个使用mmap。使用mmap的执行时间比使用malloc少得多。
例如,我知道当你使用mmap时,你会避免对系统的读/写调用,并且内存访问也会更少。
但是,使用mmap比使用malloc更有优势,还有其他原因吗?
多谢了

rsaldnfx

rsaldnfx1#

听着,伙计们,与通常的看法相反,mmap确实是一个类似于malloc的内存分配函数。
mmaped文件是它的一个用途。你可以把它作为内存分配函数使用,传递-1作为文件描述符。
所以..通常的用法是对小对象使用malloc,对大对象使用mmap。
这是个好策略。
我使用alloca()来仅用于函数作用域变量。

ev7lccsx

ev7lccsx2#

我假设您指的是使用mmapmalloc从文件中阅读数据。

  • 使用fread/fwrite,您必须对操作系统进行多次调用。
  • 使用mmap,你似乎可以在一次操作中访问整个文件。这并不完全正确,因为操作系统可能一次Map一个memory page文件,但它仍然快得多。
4xy9mtcn

4xy9mtcn3#

mmap实际上不会将文件加载到内存中,因此加载速度会更快,但编辑速度会更慢。
另一点是mmap不使用任何内存,但它占用了地址空间。在64位机器上,大部分内存地址空间都没有内存,所以你可能会加载巨大的文件,比如5GB,你不想使用malloc

mxg2im7a

mxg2im7a4#

malloc和mmap有时都很慢,这主要取决于使用模式:
mmap:内核分页子系统以页面大小为单位工作。(很好的本地化)用mmap就可以了,相反,如果你Map那个5 Gb的文件,做分散的访问,您将需要内核频繁地交换页面。除了实际的I/O之外,页面管理还需要一些时间。如果您担心延迟,避免这种访问模式,因为Linux页面回收机制往往是突发的,会导致明显的延迟,并且该高速缓存中毒会减慢其他进程。
内存分配:当你需要的内存不是以页面大小为单位的时候,这是可以的。在I/O方面,速度在很大程度上取决于你如何操作。fread/fwrite可能在后台Map页面,或者在用户空间中进行缓冲。本地化的访问将相当快。读/写直接通过内核,因此小的分布式访问仍然会导致缓存未命中导致的I/O,但是从内核-〉用户空间传输的实际数据会稍微少一点,我不知道这是否可以测量。
除非使用了mlock(),否则用户页面随时都可能被换出/写回。这也需要时间。所以在内存很少的系统上,Map最少内存的变体将获胜。在Linux内核中,每个系统的内存都太少了,因为未使用的页面被用于缓存I/O,如果内存使用或I/O是突发的,内核可能需要相当长的时间来使它们可用。

ffscu2ro

ffscu2ro5#

mmap实际上并不读取文件,它只是将文件Map到地址空间,这就是为什么它速度如此之快,在你真正访问地址空间的区域之前,没有磁盘I/O。
malloc只是地址空间到内存的Map

ua4mk5z4

ua4mk5z46#

通过mmap,不授予RAM。授予地址空间。
当地址空间被访问时,出现页面错误。在页面大小为4096字节的页面错误期间,提供RAM。
也提供RAM内容。如果通过文件备份地址空间,则会显示文件内容。如果通过MAP_ANONYMOUS备份地址空间,则会显示零初始化RAM。
通过上面的两个好处被描述。首先,完全按照所需的RAM可以被初始化。第二,直到所需的RAM没有被提供。
对于malloc请求的小于2兆字节的地址,程序中断被扩展。当提供接近程序中断的地址时,程序中断不能被收缩。因此,内核释放的RAM可能不会被返回。下面是一个类比。袜子能在鞋子之前被移除吗?
通过munmap调用内核RAM会立即返回。通过mmap和munmap使用交换概率会降低。通过malloc程序中断扩展交换概率会增加。
通过malloc可以分配小于页面大小的内存。不连续的内存变得。内核内存也可以碎片。两者都不是完美的。
在任何空闲的处理器上,内核RAM都可以进行碎片整理。2兆字节大小的透明巨大页面被创建。与512个页面错误提供2 M相比,当通过单个页面错误提供2 M时,性能将得到显著布恩。
通过mmap,至少存在一个值得注意的问题。对于支持mmap的管道文件描述符,可以使用。错误不会出现。但是,在内存地址中,管道提供的数据不会出现。
但是,如果使用MAP_ANONYMOUS,则可以从管道文件描述符到mmap提供的地址中读取数据。虽然效率不高,但可以获得所需的结果。通过lseek失败返回和errno,可以识别管道附加文件描述符。
对于可以寻址整个兆字节并运行基于磁盘的操作系统的计算机来说,malloc的使用是必不可少的。如果使用C库提供的getline函数,则可能会使用malloc和free。
在内核控制的操作系统上,为什么要使用malloc而不是mmap?mmap似乎很复杂?要调用munmap,还必须提供以前请求的地址空间量。malloc的使用更便于移植?malloc似乎更方便?
然而,如果需要性能,则使用mmap。
最后,但并非最不重要的是,如果MAP_SHARED,那么后代进程可以共享数据。避免pthreads是最重要的。有时克隆也可以避免。
虽然主观,但变量分配方法按最佳到最差列出如下:寄存器/堆栈;全局; malloc。通过每一个不同的巴内斯成为。通过一个足够复杂的程序;使用三种或可能所有四种方法。

gwo2fgha

gwo2fgha7#

总的来说(这个信息与我的学术经验密切相关),您选择使用mmap在进程之间共享内存,使用malloc在线程之间共享内存。例如:您必须在线程之间分配共享内存或信号量(首先使用malloc分配)。

相关问题