我有一个创建很多文件和目录的脚本。该脚本对处理大量文件和目录的程序进行黑盒测试。测试计数增加且测试时间过长(超过 2 秒)。我以为我在内存盘中运行测试。
我在 中运行了测试/dev/shm
。奇怪的是它并没有跑得更快。平均运行时间与普通硬盘大致相同。我也尝试过用 perl 编写的基于熔断器的 RAM 磁盘。该网站已经消失了,但我在互联网档案馆。保险丝 RAM 磁盘上的平均运行时间甚至更慢。也许是因为 perl 代码的实现不理想。
这是我的脚本的简化版本:
#! /bin/sh
preparedir() {
mkdir foo
mkdir bar
touch bar/file
mkdir bar/baz
echo qux > bar/baz/file
}
systemundertest() {
# here is the black box program that i am testing
# i do not know what it does exactly
# but it must be reading the files
# since it behaves differently based on them
find $1 -type f -execdir cat '{}' \; > /dev/null
singletest() {
mkdir actual
(cd actual; preparedir)
systemundertest actual
mkdir expected
(cd expected; preparedir)
diff -qr actual expected
}
manytests() {
while read dirname; do
rm -rf $dirname
mkdir $dirname
(cd $dirname; singletest)
done
}
seq 100 | manytests
真正的脚本会进行更多的错误检查、结果收集和摘要。这find
是我正在测试的实际程序的虚拟程序。
我想知道为什么我的文件系统密集型脚本在内存支持的文件系统上运行速度不快。是因为 Linux 内核处理文件系统缓存的效率如此之高,以至于它实际上是一个内存支持的文件系统吗?
答案1
一般来说,所有操作首先发生在 RAM 中——文件系统被缓存。该规则也有例外,但这些相当特殊的情况通常源于非常具体的要求。因此,在您开始进行缓存刷新之前,您将无法辨别其中的差异。
另一件事是,性能取决于很多在确切的文件系统上 - 有些目标是更轻松地访问大量小文件,有些目标是高效地与大文件进行实时数据传输(多媒体捕获/流媒体),有些强调数据一致性,而另一些则可以设计为具有内存/代码占用空间小。
回到你的用例:在一个循环中,你生成了大约 20 个新进程,其中大多数只创建一个目录/文件(请注意,()
创建一个子 shell 并为每个匹配find
生成cat
) - 瓶颈确实不是文件系统(如果您的系统使用ASLR而且你没有一个好的快速熵源,你的系统的随机性池也会很快耗尽)。用 Perl 编写的 FUSE 也是如此——它不是适合这项工作的工具。
答案2
比我对主要由小交易组成的测试的评论的回复要长一些。
工作量不足以测试
如果您想对文件系统进行压力测试,您将需要更大的工作集。
根据您的盒子上有多少内存,即使是数十或数千个文件夹创建操作也不会显示两者之间的明显差异。因此,修改您的工作负载以充分测试文件系统,同时考虑将用作缓冲区的内存。
有多种方法可以设计测试来抵消系统内存和其他会影响测试结果的因素的优势。
或者,您可以使用标准化测试套件,例如 bonnie++