gpt4 book ai didi

Linux/perl mmap 性能

转载 作者:IT王子 更新时间:2023-10-29 00:02:53 24 4
gpt4 key购买 nike

我正在尝试使用 mmap 优化对大型数据集的处理。数据集在千兆字节范围内。这个想法是将整个文件映射到内存中,允许多个进程同时处理数据集(只读)。但它没有按预期工作。

作为一个简单的测试,我简单地映射文件(使用 perl 的 Sys::Mmap 模块,使用我认为直接映射到底层 C 函数的“mmap”子程序)并让进程休眠。执行此操作时,代码在从 mmap 调用返回之前花费了超过一分钟的时间,尽管此测试什么也没做——甚至没有读取——来自 mmap 的文件。

我猜测,虽然 linux 可能需要在第一次 mmap 时读取整个文件,所以在第一个进程中映射文件后(当它处于休眠状态时),我在另一个进程中调用了一个简单的测试,它尝试了读取文件的前几兆字节。

令人惊讶的是,似乎第二个进程在从 mmap 调用返回之前也花费了很多时间,与第一次 mmap 处理文件的时间大致相同。

我已经确定正在使用 MAP_SHARED,并且第一次映射文件的进程仍然处于事件状态(它没有终止,并且 mmap 没有被取消映射)。

我希望一个 mmap 文件可以让多个工作进程有效地随机访问大文件,但如果每个 mmap 调用都需要先读取整个文件,那就有点困难了。我没有测试过使用长时间运行的进程来查看第一次延迟后访问是否很快,但我预计使用 MAP_SHARED 和另一个单独的进程就足够了。

我的理论是 mmap 或多或少会立即返回,而 linux 或多或少会按需加载 block ,但我看到的行为是相反的,表明它需要在每次调用时读取整个文件到 mmap。

知道我做错了什么,或者我是否完全误解了 mmap 应该如何工作?

最佳答案

好的,找到问题了。正如所怀疑的那样,linux 或 perl 都不是罪魁祸首。要打开和访问文件,我会执行以下操作:

#!/usr/bin/perl
# Create 1 GB file if you do not have one:
# dd if=/dev/urandom of=test.bin bs=1048576 count=1000
use strict; use warnings;
use Sys::Mmap;

open (my $fh, "<test.bin")
|| die "open: $!";

my $t = time;
print STDERR "mmapping.. ";
mmap (my $mh, 0, PROT_READ, MAP_SHARED, $fh)
|| die "mmap: $!";
my $str = unpack ("A1024", substr ($mh, 0, 1024));
print STDERR " ", time-$t, " seconds\nsleeping..";

sleep (60*60);

如果您测试该代码,没有像我在原始代码中发现的那样的延迟,并且在创建最小样本之后(总是这样做,对吧!)原因突然变得显而易见。

错误是我在我的代码中将 $mh 标量视为句柄,这是一种重量轻且可以轻松移动的东西(阅读:按值传递)。事实证明,它实际上是一个 GB 长的字符串,绝对不是您想要在不创建显式引用的情况下移动的东西(perl 语言表示“指针”/句柄值)。因此,如果您需要存储在散列或类似内容中,请确保存储 \$mh,并在需要像 ${$hash->{mh} 那样使用时取消引用它},通常作为 substr 或类似内容中的第一个参数。

关于Linux/perl mmap 性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1052765/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com