我正在编写一个程序,该程序涉及分析最小0.5GB(最大超过20GB)的CSV文件,我使用fstream
,while (getline(fin,line)) {}
从CSV中读取并执行平均值每个逗号分隔记录中有17毫秒的数据。简单的东西。
但是,有很多记录。显然,该程序受I / O限制,但我想知道是否可以提高I / O性能。我无法使用OpenMP,因为我会处理CPU约束,而缓冲这个大的文件也不会工作。所以我可能需要某种管道......
我在C ++中的多线程方面经验非常少,从未使用过数据流框架。有人能指出我正确的方向吗?
更新(2014年12月23日):
感谢您的所有评论。你是对的,17ms有点多......在做了大量的分析(哦,痛苦)之后,我把瓶颈分离为每个记录中一个子串的迭代(75个字符)。我尝试了#pragmas
,但它并不足以并行化。函数调用的开销是主要的抱怨 - 现在每条记录5.41μs,已经移动了一个大块。它很难看,但更快。
感谢@ChrisWard1000的建议。不幸的是,我现在对我正在使用的硬件没有多少控制权,但会使用更大的数据集(> 20GB CSV)进行分析,看看我如何引入mmap /多线程解析等。
答案 0 :(得分:8)
升级硬件。 SSD,RAID条带化和PCI Express硬盘专为此类活动而设计。
一次以较大的块读取文件,减少I / O等待时间。也许首先使用fread将大块数据转储到内存中。
考虑使用mmap映射硬盘和内存之间的指针。
最重要的是对您的代码进行分析,以查看延迟的位置。对于I / O活动而言,这是非常困难的,因为它在不同的机器之间有所不同,并且在运行时通常会有很大差异。
您可以尝试添加多线程解析,但我强烈建议您将此作为最后的手段,并了解它可能会造成很多痛苦和痛苦。
答案 1 :(得分:0)
getline
可能会引入一些可能会影响性能的CPU开销,但最终,如果你耗尽了硬盘的读取速度,没有管道,多线程或其他任何东西都会对你有所帮助。只有增加I / O带宽才能帮助您,这就是硬件问题(例如,将其放在RAID0上,从网络收集部件等)。
答案 2 :(得分:0)
大多数分析器的问题,正如您所发现的,要么是1)忽略您的I / O,要么它们2)只给您功能级别的时序,而不是行级别。
一种非常简单的方法可以同时为您提供shown here。
你的程序应该是I / O绑定的,这意味着如果你暂停10次,几乎每次你都会在获取下一条记录的过程中看到它。
如果您每秒只处理160条记录,则不受I / O限制,您受CPU限制,几乎每次暂停都会指向您的解析或其他任何内容。
例如,您可能new
(以及稍后删除)了许多对象。如果是这样,请重复使用它们。
无论指向什么,都要找到减少或消除这种活动的方法。 将加速你。
冲洗并重复。当你受I / O限制时,你可以停止。