5

我正在实现一个基于磁盘的哈希表,支持大量键(26+ 百万)。该值被反序列化。整个文件的读取基本上是随机的,值小于页面大小,我正在针对 SSD 进行优化。安全/一致性不是那么大的问题(性能问题)。

我当前的解决方案包括使用一个mmap()文件MADV_RANDOM | MADV_DONTNEED来禁用内核预取,并且只按需加载数据。

我知道内核从磁盘读取到内存缓冲区,然后从那里反序列化。

怎么样O_DIRECT?如果我打电话read(),我仍在复制到缓冲区(我从中反序列化),所以我可以获得任何优势吗?

我在哪里可以找到有关文件涉及的缓冲区mmap()和调用read()打开的文件的更多信息O_DIRECT

我对预读或缓存不感兴趣。它对我的用例没有任何好处。

4

1 回答 1

6

O_DIRECT 是读/写操作的选项,当数据绕过系统缓冲区并直接从缓冲区复制到磁盘控制器时。为了获得 O_DIRECT 的优势,需要遵守一些条件 - 保持与内存页缓冲区地址对齐和由 I/O 块对齐的缓冲区大小。

无论如何,如果您使用 mmap,则不使用读/写。此外,在 mmap 之后,您可以关闭文件描述符,映射仍然有效。因此,O_DIRECT 对 mmap 选项毫无用处。

我可以推荐什么来提高性能:

  1. 如果您的子系统有很多搜索缺失键的请求,您可以在内存中创建布隆过滤器。此后,您在 Bloom 过滤器http://en.wikipedia.org/wiki/Bloom_filter上匹配您的搜索键,并拒绝丢失的键,而无需实际请求磁盘。

  2. 为了节省内存,请使用 2 级方案,当桶头保存在 mmap 内存中时,但桶本身是通过 pread() 从文件中读取的。

我在我的自动完成子系统中实现了这两个选项,您可以在这里在线查看:http://olegh.ftp.sh/autocomplete.html估计慢旧计算机 - Celeron-300 的性能。

于 2013-11-12T16:12:19.663 回答