[英]Can mmap's performance be improved for shared memory?
我正在为 Wayland 编写一个使用软件渲染和wl_shm进行显示的小程序。 这要求我将屏幕缓冲区的文件描述符传递给 Wayland 服务器,然后在其上调用mmap()
,即屏幕缓冲区必须在进程之间共享。
在这个程序中,启动延迟是关键。 目前,只剩下一个瓶颈:初始绘制到屏幕缓冲区,整个缓冲区都被绘制。 下面的代码显示了这个的简化版本:
#define _GNU_SOURCE
#include <unistd.h>
#include <sys/mman.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
/* Fullscreen buffers are around 10-30 MiB for common resolutions. */
const size_t size = 2880 * 1800 * 4;
int fd = memfd_create("shm", 0);
ftruncate(fd, size);
void *pool = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
/* Ideally, we could just malloc, but this memory needs to be shared. */
//void *pool = malloc(size);
/* In reality this is a cairo_paint() call. */
memset(pool, 0xCF, size);
/* Subsequent paints (or memsets) after the first take negligible time. */
}
在我的笔记本电脑上,上面的memset()
大约需要 21-28 毫秒。 切换到malloc()
'ed memory 将此时间降至 12 ms,但问题是 memory 需要在进程之间共享。 我的桌面上的行为类似: mmap()
为 7 ms, malloc()
为 3 ms。
我的问题是:我是否缺少可以提高 Linux 上共享 memory 的性能的东西? 我试过madvise()
和MADV_WILLNEED
和MADV_SEQUENTIAL
,并使用mlock()
,但这些都没有改变。 考虑到大约 10-30 MB 的缓冲区大小,我还考虑过 2MB Huge Pages 是否会有所帮助,但这通常不可用。
编辑:我试过mmap()
和MAP_ANONYMOUS | MAP_SHARED
MAP_ANONYMOUS | MAP_SHARED
,它和以前一样慢。 MAP_ANONYMOUS | MAP_PRIVATE
MAP_ANONYMOUS | MAP_PRIVATE
导致与malloc()
相同的速度,但这违背了目的。
malloc()
和mmap()
之间的性能差异似乎是由于Transparent Hugepages的不同应用。
默认情况下,在 x86_64 上,页面大小为 4KiB,大页面大小为 2MiB。 透明大页面允许不知道大页面的程序仍然使用它们,从而减少页面错误。 这仅在默认情况下对私有匿名 memory 启用 - 因此对于带有 MAP_ANONYMOUS 的malloc()
和mmap()
MAP_ANONYMOUS | MAP_PRIVATE
MAP_ANONYMOUS | MAP_PRIVATE
集,解释了为什么这些性能是相同的。 对于共享的 memory 映射,这是禁用的,导致更多的页面处理开销(对于我需要的 10-30MiB 缓冲区),并导致速度变慢。
可以通过/sys/kernel/mm/transparent_hugepage/shmem_enabled
旋钮为共享 memory 映射启用大页面,如kernel 文档页面中所述。 这默认为never
,但将其设置为always
(或advise
,并添加相应的madvise(..., MADV_HUGEPAGE)
调用)允许使用MAP_SHARED
映射的 memory 使用大页面,并且性能匹配malloc()
'ed memory。
我不确定为什么默认值never
用于共享 memory。 虽然不是很令人满意,但目前看来唯一的解决方案是使用madvise(MADV_HUGEPAGE)
来提高任何系统的性能,这些系统恰好将shmem_enabled
设置为至少advise
(或者将来默认启用)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.