【问题标题】:Is there any possibility of getting some performance gain on fstream (file read) by using openMP是否有可能通过使用 openMP 在 fstream(文件读取)上获得一些性能提升
【发布时间】:2023-03-25 21:35:01
【问题描述】:

我想知道使用 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是如何处理并行文件读取操作的。

【问题讨论】:

    标签: c++ openmp fstream


    【解决方案1】:

    正如您所提到的,您不太可能通过并行任何类型的 I/O 绑定任务来获得任何加速。然而,还有一个更大的问题。代码甚至都不正确。

    seekg()read() 方法修改 file 变量。所以你的迭代不是独立的。因此,您将在流上遇到竞争条件。换句话说,循环不可并行化。

    因此,不要指望该代码能够正常工作 - 更不用说具有更好的性能了。

    【讨论】:

      【解决方案2】:

      虽然文件流有很多性能改进,但您提出的这些改进不在其中:

      • std::streambuf 是有状态的,尝试从多个执行线程同时访问它会彻底搞砸。
      • 处理单个字符本质上是当代处理器的最坏情况。如果您真的最终并行执行,您将有多个处理器处理相同的缓存行。与单线程执行相比,这实际上会显着降低性能。
      • 我不知道为什么人们如此喜欢使用搜索:每次搜索基本上都会杀死任何当前缓冲区,并且可能会导致系统调用只是将流定位到定义的状态。寻找的关键问题是,将流设置为读取或写入,这取决于下一个操作是什么。是的,可能会考虑开放模式,但可能不会。

      如果您想使用std::ifstream 快速读取文件,您应该

      • imbue() 一个 std::locale 宣传不进行任何转换
      • std::binary模式打开文件
      • 跳过试图得到对文件大小的错误估计(一直到最后并希望这能以某种方式为您提供文件中的字符数是徒劳的)
      • 阅读合适的std::ostream,例如std::ostringstream(如果您可以提供目标缓冲区,则可以使用更快的输出流)对流缓冲区使用输出运算符:out &lt;&lt; in.rdbuf()

        我认为并发不会帮助您阅读流。

      【讨论】:

        猜你喜欢
        • 2011-02-05
        • 2012-01-15
        • 2012-03-19
        • 2011-07-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-09-17
        • 1970-01-01
        相关资源
        最近更新 更多