这个问题在 StackOverflow 上经常出现,但是我已经阅读了之前所有的相关答案,并且对这个问题有轻微的扭曲。
我有一个 23Gb 的文件,其中包含 4.75 亿行大小相等的行,每行包含一个 40 个字符的哈希码,后跟一个标识符(一个整数)。
我有一个传入的哈希码流——总共有数十亿个——对于每个传入的哈希码,我需要找到它并打印出相应的标识符。这项工作虽然很大,但只需要完成一次。
该文件太大,我无法读入内存,因此我一直在尝试通过以下方式使用 mmap:
codes = (char *) mmap(0,statbuf.st_size,PROT_READ,MAP_SHARED,codefile,0);
然后我只是根据代码中的地址使用地址算法进行二进制搜索。
这似乎开始工作得很好,并在几秒钟内产生了几百万个标识符,使用了 100% 的 cpu,但是在经过一些看似随机的时间后,它会减速到爬行。当我使用 ps 查看进程时,它已从使用 100% 的 cpu 的状态“R”变为使用 1% 的 cpu 的状态“D”(磁盘绑定)。
这是不可重复的——我可以在相同的数据上再次启动该过程,并且它可能会在“爬行缓慢”发生之前运行 5 秒或 10 秒。昨晚有一次,在这件事发生之前我花了将近一分钟的时间。
一切都是只读的,我没有尝试对文件进行任何写入,并且我已经停止了机器上的所有其他进程(我控制的)。它是现代 Red Hat Enterprise Linux 64 位机器。
有谁知道为什么该进程成为磁盘绑定以及如何停止它?
更新:
感谢大家的回答和您的想法;我以前没有尝试过所有各种改进,因为我想知道我是否以某种方式错误地使用了 mmap。但答案的要点似乎是,除非我能将所有内容都挤进内存,否则我将不可避免地遇到问题。所以我将散列码的大小压缩到不产生任何重复的前导前缀的大小——前 15 个字符就足够了。然后我将生成的文件拉入内存,并以大约 20 亿个批次运行传入的哈希码。