21

我今天刚刚迈出了真正的科学计算的第一步,当时我看到一个数据集,其中最小的文件是 48000 个字段乘 1600 行(几个人的单倍型,对于 22 号染色体)。这被认为是微小的。

我编写 Python,所以在过去的几个小时里我一直在阅读有关 HDF5、Numpy 和 PyTable 的内容,但我仍然觉得我并没有真正理解 TB 大小的数据集对我作为程序员的实际意义。

比如有人指出,数据集比较大,把整个东西读进内存就变得不可能了,不是因为机器内存不够,而是因为架构地址空间不够!这让我大吃一惊。

我在课堂上还依赖于哪些其他假设在输入这么大的情况下不起作用?我需要开始以不同的方式做或思考哪些事情?(这不一定是特定于 Python 的。)

4

4 回答 4

18

我目前在石油行业的一个小角落从事高性能计算,并定期处理您关注的数量级的数据集。以下是需要考虑的几点:

  1. 数据库在这个领域没有太大的吸引力。我们几乎所有的数据都保存在文件中,其中一些文件是基于 70 年代设计的磁带文件格式。我认为不使用数据库的部分原因是历史性的;10 年,甚至 5 年前,我认为 Oracle 及其同类产品无法胜任管理 O(TB) 的单个数据集的任务,更不用说包含 1000 多个此类数据集的数据库了。

    另一个原因是有效数据库分析和设计的规范化规则与科学数据集的性质在概念上不匹配。

    我认为(尽管我不确定)性能原因今天的说服力要小得多。而且,由于大多数可用的主要数据库都可以处理空间数据集,这些数据集通常更接近其他科学数据集的概念拟合,因此概念不匹配的原因可能也不那么紧迫。我已经看到越来越多地使用数据库来存储元数据,然后对包含传感器数据的文件进行某种引用。

    但是,我仍然在看,实际上是在看 HDF5。它对我有几个吸引力(a)它只是另一种文件格式,因此我不必安装 DBMS 并与其复杂性作斗争,并且(b)使用正确的硬件我可以并行读取/写入 HDF5 文件. (是的,我知道我也可以并行读写数据库)。

  2. 这将我带到第二点:在处理非常大的数据集时,您确实需要考虑使用并行计算。我主要在 Fortran 中工作,它的优势之一是它的数组语法非常适合许多科学计算;另一个是对可用并行化的良好支持。我相信 Python 也有各种并行化支持,所以它对你来说可能不是一个糟糕的选择。

    当然,您可以将并行性添加到顺序系统中,但最好从设计并行性开始。仅举一个例子:解决问题的最佳顺序算法通常不是并行化的最佳候选者。使用不同的算法可能会更好,这种算法可以在多个处理器上更好地扩展。这巧妙地引出了下一点。

  3. 我还认为,您可能不得不接受将您拥有的任何附件(如果有的话)交给许多聪明的算法和数据结构,当您的所有数据都驻留在内存中时,这些算法和数据结构运行良好。经常尝试使它们适应无法一次将数据全部放入内存的情况,这比蛮力和将整个文件视为一个大数组要困难得多(并且性能较低)。

  4. 性能开始变得很重要,包括程序的执行性能和开发人员的性能。并不是说 1TB 数据集需要 10 倍于 1GB 数据集的代码,因此您必须更快地工作,而是您需要实施的一些想法将非常复杂,并且可能必须由领域专家编写,即与您合作的科学家。这里是领域专家用 Matlab 编写的。

不过时间太长了,我还是回去工作吧

于 2010-06-10T07:55:52.107 回答
5

简而言之,IMO的主要区别:

  1. 您应该事先知道您可能的瓶颈是什么(I/O 或 CPU),并专注于解决这个问题的最佳算法和基础设施。I/O 经常是瓶颈。
  2. 算法的选择和微调通常支配任何其他选择。
  3. 即使是对算法和访问模式的适度更改也会对性能产生数量级的影响。您将进行很多微优化。“最佳”解决方案将取决于系统。
  4. 与您的同事和其他科学家交谈,从他们使用这些数据集的经验中获益。很多技巧是教科书上找不到的。
  5. 预计算和存储可以非常成功。

带宽和 I/O

最初,带宽和 I/O 通常是瓶颈。给你一个观点:在SATA 3的理论极限下,读取 1 TB 大约需要 30 分钟。如果您需要随机访问、多次读取或写入,您希望大部分时间在内存中执行此操作,或者需要更快的东西(例如带有InfiniBand的iSCSI)。理想情况下,您的系统应该能够执行并行 I/O,以尽可能接近您使用的任何接口的理论极限。例如,简单地在不同的进程中并行访问不同的文件,或者在MPI-2 I/O之上的HDF5很常见。理想情况下,您还可以并行执行计算和 I/O,以便两者之一是“免费的”。

集群

根据您的情况,I/O 或 CPU 可能会成为瓶颈。无论是哪一种,如果您能够有效地分配任务(例如MapReduce),集群都可以实现巨大的性能提升。这可能需要与典型教科书示例完全不同的算法。在这里花费开发时间通常是最好的时间。

算法

在算法之间进行选择时,算法的大 O 非常重要,但是具有相似大 O 的算法在性能上可能会因局部性而有很大差异。算法的局部性越小(即缓存未命中和主存未命中越多),性能就越差 - 访问存储通常比主存慢一个数量级。改进的经典示例是矩阵乘法或循环交换的平铺

计算机、语言、专业工具

如果您的瓶颈是 I/O,这意味着大型数据集的算法可以受益于更多的主内存(例如 64 位)或内存消耗更少的编程语言/数据结构(例如,在 Python 中__slots__可能有用),因为更多的内存可能意味着每个 CPU 时间的 I/O 更少。顺便说一句,具有 TB 主存储器的系统并非闻所未闻(例如HP Superdomes)。

同样,如果您的瓶颈是 CPU,那么允许您使用架构的特殊功能(例如SIMD,如SSE)的更快的机器、语言和编译器可能会将性能提高一个数量级。

The way you find and access data, and store meta information can be very important for performance. You will often use flat files or domain-specific non-standard packages to store data (e.g. not a relational db directly) that enable you to access data more efficiently. For example, kdb+ is a specialized database for large time series, and ROOT uses a TTree object to access data efficiently. The pyTables you mention would be another example.

于 2010-06-10T09:15:57.103 回答
1

虽然某些语言在其类型中的内存开销自然比其他语言低,但对于这种大小的数据来说,这并不重要 - 无论您使用哪种语言,您都不会将整个数据集保存在内存中,因此“费用” Python的在这里无关紧要。正如您所指出的,根本没有足够的地址空间来引用所有这些数据,更不用说保留它了。

这通常意味着 a) 将您的数据存储在数据库中,或者 b) 以附加计算机的形式添加资源,从而增加您的可用地址空间和内存。实际上,你最终会做这两件事。使用数据库时要记住的一件关键事情是,数据库不仅仅是在您不使用它时放置数据的地方 - 您可以在数据库中进行 WORK 工作,并且您应该尝试这样做。您使用的数据库技术对您可以完成的工作类型有很大影响,但是例如,SQL 数据库非常适合进行大量数学运算并且可以高效地完成(当然,这意味着架构设计变得整体架构的一个非常重要的部分)。大学教师'

于 2010-06-10T07:13:01.983 回答
0

主要假设是关于您可以以可接受的价格在单台机器中拥有的 CPU/缓存/内存/存储/带宽的数量。在 stackoverflow 上有很多答案仍然基于具有 4G 内存和大约 1 TB 存储和 1Gb 网络的 32 位机器的旧假设。使用 220 欧元的 16GB DDR-3 内存模块,512 GB 内存,可以以合理的价格构建 48 核机器。从硬盘到 SSD 的转变是另一个重要的变化。

于 2012-04-01T13:23:08.810 回答