【发布时间】:2021-04-28 05:09:47
【问题描述】:
未来人们的 TLDR: 我继承了一个程序,需要对其进行调整以处理比现在大几个数量级的数据。我需要帮助找出管理 30GB 数组的多个副本的方法。
我最近继承了一些研究代码(用 c 编写),最初是为了在相对约 5 GB 的一小部分数据上运行而编写的。该代码要求我能够一次访问该数组的四个副本(一个char 数组和三个double 数组)。因此,当时的作者无需担心内存使用情况,因此有多个实例,其中内存中同时存在 2-4 个额外数组。
另外,这是生物数据(基因组),数组并不稀疏。
现在的问题是我必须使代码适应单个双精度数组为 30GB 的情况。
我不确定是否需要一次访问所有值,但我知道代码循环遍历所有值的情况很常见。
我尝试过的事情
用文件模拟恒定时间访问
我将每个数组拆分为 10k 个字符或双精度的集合,并将它们全部写入文件。然后我更改了对我自己的函数的所有访问权限,并让它从文件中读取或覆盖文件中的那一行。虽然这行得通。问题是它非常慢(很可能是由于所有文件的打开和关闭+写入磁盘的速度),这已经是程序的问题,我不想让它变得更糟。
在不需要时将数组写入磁盘
我注意到有很多时候程序不需要数组,我决定将它写入磁盘,然后在需要时从它读取。我面临的问题是,将整个数组写入磁盘仍然需要很长时间(10 分钟+?),只需打开文件并关闭一次(与上述方法不同)。
使用更多内存
由于这是为了研究,我确实可以访问具有 150GB RAM 的计算集群。我将此程序作为作业提交,但不幸的是,即使如此,该过程也因占用过多内存而被杀死。我最初怀疑这只是内存泄漏,但经过进一步检查,确实似乎在程序运行时创建了 >5 个双数组。就像旁注个人机器有 40(我知道的一个奇怪的数字)GB 内存一样。
愚蠢的最后一搏
我禁止内核过度使用内存,因为我注意到它不是在分配许多数组时崩溃,而是在它实际开始访问它们时崩溃。但是,我认为这最终没有做任何事情,因为它仍然过度承诺。
一天晚上,我对它一直被杀死感到非常沮丧,并决定以 -10000 的精度运行该程序,这导致我的计算机崩溃,因为它杀死了其他进程以弥补更多内存。
我也尝试过使用mmap(),但不确定这是否是我应该追求的。
为什么需要这么多内存?这是 XY 问题吗?
虽然我真的不能确定这是否是一个 XY 问题,但我很有信心我需要同时拥有至少三个数组(尽管我不会在数组中跳来跳去太多)。
有没有人知道如何解决这个问题?提前谢谢你的帮助。最后,我使用的是 Linux。
【问题讨论】:
-
让 Linux 内存管理器为您处理所有这些。只需购买尽可能多的 RAM,购买一个不错的快速 SSD 并将其连接到系统上最快的总线,然后调整 Linux 环境的交换文件大小为数据腾出空间。
-
感谢您的评论!我会尝试增加交换空间。有 200GB 的交换空间可以吗?
-
内存映射文件是让您的应用程序在因违反其使用政策而被踢出局的大铁杆上被接受的方式。如果您不与其他进程共享空间,您可能会很好。使用 mmap,每个数组都有一个文件,然后调整内存块的大小以适合您的系统策略。它本质上使用与交换文件相同的算法,但范围不同。
-
这些是运行 64 位版本的 Linux 的 64 位机器吗?
-
我想是的。检查他们的政策,但这对我来说似乎是系统管理的东西。还有一点需要注意:如果您的磁盘有碎片,则增加交换文件的大小可能会失败。或者至少以前交换文件必须是连续的。因此,我偏爱专用交换磁盘。
标签: c linux dataset bioinformatics