- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在尝试微调 mmap()
以对可能非常大的文件执行快速写入或读取(通常不是两者)。写入和读取在一次通过时大部分将是连续的,然后在以后的通过中可能非常稀疏。不需要多次访问内存区域。
换句话说,可以将其视为具有一些异步修复的损失的文件传输。
正如预期的那样,mmap()
性能的主要限制似乎是它在大文件上生成的次要页面错误的数量。此外,我怀疑 Linux 内核页面到磁盘的惰性导致了一些性能问题。即,任何最终对 mmap
ed 内存执行大量写入的测试程序在执行所有写入以终止/munmap
内存后似乎需要很长时间。
我希望通过在执行几乎顺序的访问和调出不再需要的页面的同时对页面进行预故障来抵消这些错误的成本。但我对这种方法和我对该问题的理解有三个主要问题:
MAP_POPULATE
标志,但这似乎试图将整个文件加载到内存中,这在许多情况下是无法容忍的。此外,这似乎会导致 mmap()
调用阻塞,直到预故障完成,这也是无法容忍的。我对手动替代方案的想法是生成一个线程,以尝试读取内存中的下一个 N
页以强制进行预取。但实际上,带有 MADV_SEQUENTIAL
的 madvise
可能已经这样做了。 msync()
可用于将更改刷新到磁盘。然而,定期这样做真的有用吗?我的想法是,如果程序经常处于磁盘 IO 的“空闲”状态并且能够承受一些磁盘写回,它可能会有用。话又说回来,内核很可能比以往的应用程序更好地处理它。 msync()
调用阻塞了所有磁盘 IO,包括文件系统缓存和原始文件系统,那么使用它来刷新整个磁盘的动机也不大在程序终止时缓存。最佳答案
It appears, as expected, that the main limitation of mmap()'s performance seems to be the number of minor page faults it generates on large files.
这并不特别令人惊讶,我同意。但这是无法避免的成本,至少对于与您实际访问的映射文件区域对应的页面而言。
Furthermore, I suspect the laziness of the Linux kernel's page-to-disk is causing some performance issues. Namely, any test programs that end up performing huge writes to mmaped memory seem to take a long time after performing all writes to terminate/munmap memory.
这是有道理的。同样,这是不可避免的成本,至少对于脏页而言是这样,但您可以对何时产生这些成本施加一些影响。
I was hoping to offset the cost of these faults by concurrently prefaulting pages while performing the almost-sequential access and paging out pages that I won't need again. But I have three main questions regarding this approach and my understanding of the problem:
- Is there a straightforward (preferably POSIX [or at least OSX] compatible) way of performing a partial prefault? I am aware of the
MAP_POPULATE
flag, but this seems to attempt loading the entire file into memory,
是的,这与其文档一致。
which is intolerable in many cases. Also, this seems to cause the
mmap()
call to block until prefaulting is complete,
这也是记录在案的。
which is also intolerable. My idea for a manual alternative was to spawn a thread simply to try reading the next N pages in memory to force a prefetch.
除非在您最初 mmap()
文件和您想要开始访问映射之间有延迟,否则我不清楚为什么您会期望它提供任何改进。
But it might be that madvise with
MADV_SEQUENTIAL
already does this, in effect.
如果您想要 POSIX 兼容性,那么您正在寻找 posix_madvise()
。我确实建议使用此功能,而不是尝试推出您自己的用户空间替代方案。特别是,如果您使用 posix_madvise()
在部分或所有映射区域上断言 POSIX_MADV_SEQUENTIAL
,那么有理由希望内核会提前读取以加载页面在需要它们之前。此外,如果您使用 POSIX_MADV_DONTNEED
建议,那么根据内核的判断,您可能会更早地同步到磁盘并减少整体内存使用。如果有用,您也可以通过此机制传递其他建议。
msync()
can be used to flush changes to the disk. However, is it actually useful to do this periodically? My idea is that it might be useful if the program is frequently in an "Idle" state of disk IO and can afford to squeeze in some disk writebacks. Then again, the kernel might very well be handling this itself better than the ever application could.
这是要测试的东西。但是请注意,msync()
支持异步 同步,因此您不需要 I/O 空闲。因此,当您确定已完成给定页面时,您可以考虑使用 msync()
标记 MS_ASYNC
来请求内核安排同步。这可能会减少取消映射文件时产生的延迟。您必须尝试将它与 posix_madvise(..., ..., POSIX_MADV_DONTNEED)
结合使用;它们可能会或可能不会相互补充。
- Is my understanding of disk IO accurate? My assumption is that prefaulting and reading/writing pages can be done concurrently by different threads or processes; if I am wrong about this, then manual prefaulting would not be useful at all.
一个线程应该有可能预置页面(通过访问它们),而另一个线程读取或写入其他已经出错的页面,但我不清楚为什么你期望这样一个预置线程能够提前运行做读写的人。如果它有任何影响(即如果内核不自行预故障)那么我预计预故障页面比读取或写入每个字节一次更昂贵。
Similarly, if an
msync()
call blocks all disk IO, both to the filesystem cache and to the raw filesystem, then there also isn't as much of an incentive to use it over flushing the entire disk cache at the program's termination.
代表您的程序需要执行的磁盘读取和写入次数最少。对于任何给定的映射文件,它们都将在同一 I/O 设备上执行,因此它们都将相对于彼此进行序列化。如果您受 I/O 限制,那么第一近似值是,执行这些 I/O 操作的顺序对整体运行时间无关紧要。
因此,如果运行时是您所关心的,那么 posix_madvise()
和 msync()
可能都没有多大帮助,除非您的程序花费其运行时间的很大一部分是在独立于访问映射文件的任务上进行的。如果您确实发现自己并非完全受 I/O 限制,那么我的建议是先看看 posix_madvise()
能为您做什么,然后尝试异步 msync()
如果你需要更多。我倾向于怀疑用户空间预故障或同步 msync()
是否会带来胜利,但在优化中,测试总是比(仅)预测更好。
关于c - `mmap()` 手动并发预故障/分页,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47677137/
有人可以解释一下为什么这个脚本不起作用吗? function destroy(ID) { if (confirm("Deleting is a very bad thing! Sure?")
我正在尝试使 WCF Silverlight 故障按此方式工作: MSDN aricle 将 SL 故障添加到我的 Web.config 文件后,我收到以下警告: The element 'behav
这是我要删除的 Haskell 函数 2::Int和 5::Int从列表中: remPrimesFactors25 :: [Int] -> [Int] remPrimesFactors25 [] =
当我想用 ffmpeg 连接和录制两个 mp4 视频时,我遇到了这个问题。我得到的输出是: [concat @ 0x2566e80] DTS 4079 #0:0 (h264 (native) ->
我想在delphi中编写一个程序来模拟以特定速度移动的鼠标指针(类似于AutoIT MouseMove函数)。要么是我的代码错误,要么是 SetCursorPos 在被调用太多次后出现故障。这是我的功
我将“wa、or 和 id”(来自这些州的访问者)设置为重定向到 website1.com - 当我访问该网站时,它会将我重定向到 website1.com(因此它知道我在 WA) 。但如果我将 wa
我们目前正在争论通过 WCF channel 抛出错误与传递指示状态或服务响应的消息是否更好。 故障带有 WCF 的内置支持,您可以使用内置的错误处理程序并做出相应的 react 。然而,这会带来开销
不确定我在这里做错了什么,如果有任何帮助,我们将不胜感激。 尝试创建一个名为“control”的新变量,并在行变量等于这些数字时将其编码为 1,否则编码为 0。 data$control= ifels
我想在应用洞察中记录成功调用的百分比。我看到这篇文章https://learn.microsoft.com/en-us/azure/azure-monitor/app/sampling我认为固定速率采
我正在尝试使用 SVD 和特征分解来使用动态模式分解进行一些数据分析。我遇到了一个简单的问题,即从 Matlab 和 Python 获得不同的结果。我很困惑,不知道为什么 Python 给我错误的结果
This question already has an answer here: mysqli_fetch_assoc() expects parameter / Call to a member
我刚刚开始我的一个实验室,在那里我计算类(class)的 GPA,其信息存储在结构的链接列表中。截至目前,我正在尝试打印所有类(class)信息,以确保它们已正确初始化并添加到链接列表中。 我遇到了一
我正在尝试学习如何使用 visual studio 为 C++ 制作 GUI。但是我在使用 GetWindowText() 函数时遇到了一些问题。它不会将 LPTSTR 标题更改为文本框中的文本,并且
我有一个奇怪的问题。它似乎只出现在测试者的 iPhone 5s 上。它可以在运行最新 iOS (8.3) 的 iPhone 5、6 和 6 plus 上正常运行。 这是代码 -(NSString *)
我正在尝试更新 Core Data 中的一些记录。我正在采取以下步骤来完成它 带谓词的获取函数从核心数据中检索记录 将结果集存储在对象数组中 遍历数组并更新每条记录 调用保存上下文 我遇到了两个问题
我通过 Storyboard设计了 tableView,在一个单元格中我有一个按钮和一个标签。按钮在 Storyboard上有标签 1 和标签在 Storyboard上有标签 2。在 cellForR
我实现了这个方法,当在文本字段中输入了未经授权的字符或已使用的用户名时,向用户发送多个警报 View : func textFieldShouldEndEditing(textField: UITex
伙计们,我在运行程序时遇到了这个非常奇怪的错误。这是重要的代码: 变量(编辑): const short int maxX = 100; const short int maxZ = 100; con
我有这个修改过的 Matrix Javascript 代码,我想摆脱第一次运行的所有与自身重叠的字符串。有人知道我该如何管理吗?另外,我想在我的网页上多次使用此代码,我需要声明新变量,不是吗?但是当我
有谁知道是否有网站(甚至非 Microsoft)有关于 COMExceptions/HRESULTS 的详细信息。 当我尝试在使用 Copy() 函数后保存我的 Excel 工作簿时,我收到此错误:
我是一名优秀的程序员,十分优秀!