使用OpenMP可以提高fstream(文件读取)的性能吗?是否有可能获得一些性能增益?

3
我希望知道是否有可能通过使用OpenMP在文件读取方面获得一些性能提升。
示例代码:
fstream file;

file.open("test.txt",ios::in);

file.seekg(0,ios::end);

int len = file.tellg();

char *arr = new char[len];

char *temp = new char[1];

int i;

#pragma omp parallel for shared(arr, len) private(temp, i)
for(i = 0; i < len; i++)
{
    file.seekg(i);
    file.read(temp,1);
    arr[i] = temp[0];
}

我认为使用多个线程进行I/O操作是一个不好的选择,因为最终文件读取操作将被串行化。但是,我仍然想知道是否可以期望性能提升。此外,我还想知道openMP如何处理并行文件读取操作。

2个回答

7
正如你所提到的,像这样的I/O绑定任务并不能通过并行化来加速。然而,存在一个更大的问题。该代码甚至是不正确的。seekg()read()方法会修改file变量。因此,你的迭代不是独立的。所以你将在流上遇到竞争条件。换句话说,这个循环是不可并行化的。因此,不要指望这个代码能够工作 - 更别提有更好的性能了。

3
虽然文件流中有很多性能提升,但您提出的内容并不属于其中之一:
- std::streambuf是有状态的,试图从多个执行线程同时访问它将会彻底搞乱它。 - 处理单个字符实际上是当代处理器的最坏情况。如果您真的最终以并行方式执行此操作,则会有多个处理器同时干扰相同的缓存行。这实际上会导致性能比单个执行线程大大降低。 - 我不知道人们为什么如此喜欢使用寻找:每次寻找本质上都会破坏当前缓冲区,并可能导致系统调用来将流定位到定义的状态。寻找的关键问题在于将流设置为读取或写入,具体取决于下一个操作是什么。是的,打开模式可能会被考虑进去,但可能并没有。
如果您想快速阅读使用std :: ifstream的文件,请执行以下操作:
- imbue()std :: locale,该std :: locale广告不进行任何转换 - 以std :: binary模式打开文件 - 跳过尝试获取可能是错误估计的文件大小(跳到结束并希望这样做可以获得文件中的字符数是徒劳的) - 使用输出运算符读取适当的std :: ostream,例如std :: ostringstream(如果您可以提供目标缓冲区,则可以使用更快的输出流):out << in.rdbuf() 我不认为并发会帮助您阅读流。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接