gpt4 book ai didi

c++ - 使用C++ OpenMP和文件io进行并行化。性能问题

转载 作者:行者123 更新时间:2023-12-03 07:26:12 27 4
gpt4 key购买 nike

问题本质上是在一个较大的(> 20GB)数据文件上计算一些函数void lineProcess(string, string&, int[]),该计算相当繁琐,并且还非常依赖于输入行的长度和array参数引入的一些随机性,因此我将几次平均测试运行。第一个参数是文件的一行,第二个参数是字符串的地址,因此可以输出结果。输出的总大小为3MB。不需要输入和输出的第k行对应。除了文件io之外,它听起来很适合并行化,因此这里是代码。

void foo(const int param[]) {
// process some stuff ...
// create input stream fin, output stream fout from <iostream>
string result;
for (string line; getline(fin, line);) {
#pragma omp parallel task firstPrivate(result)
lineProcess(line, result, param);
fout << result << endl;
}
#pragma omp task wait
fin.close();
fout.close();
}

我已经在笔记本电脑上运行了几次(i7四核,应该支持8个带有超线程的进程),并且似乎并没有看到太多的速度提升。串行线路处理(即上述减去pragama指令)的平均时间为每行2800秒,并行的平均时间为2000秒。我的目标是每线约600秒。我认为问题的一部分可能是使用task和taskwait的openMP实现,但是由于我不知道文件中的行数,因此看不到使用 #pragma omp for的简便方法。
理想情况下,我正在尝试一个读入行和结果之一的缓冲区,并处理所有线程,直到一个缓冲区几乎为空/满,然后线程通过读取/写入磁盘交换为重新填充/清空它,但是我不是确保在OpenMP中是否可以做到这一点,或者我是否可以用一个线程在读/写之间单独交换来做一个简单的版本。
任何关于为什么不如预期那样快或如何提高性能的建议,将不胜感激。显然,必须读写大量数据存在根本的限制,但是我知道行处理也要花费大量时间。

我使用非常相似的方法 openmp - while loop for text file reading and using a pipeline找到了这个问题,第一个答案与我的代码匹配得很好,但是第二个答案似乎正在使用缓冲区,但是我不确定如何完全适应它或是否值得。

最佳答案

您应该在for循环之前打开并行区域。这将生成一个运行多个线程的并行区域。在创建任务的那一刻,已有线程启动并准备好执行您的任务。

#pragma omp parallel
{
#pragma omp single
{
for(...)
{
#pragma omp task
lineProcess(...)
fout ...
}
}
#pragma omp taskwait
}

在这里,首先打开并行区域,然后指出,仅通过一个线程(该线程正在生成任务)就增加了该线程,而该任务又由多个线程工作。处理完所有行(任务等待)后,可以继续执行常规代码。

您还应该注意,只有lineProcess函数是一项任务。生成任务(尚未完成或尚未完成)后,您的生成线程将移至检测线并对其进行处理。您可以像这样解决它:
#pragma omp task
{
lineProcess(...)
fout ...
fout.flush();
}

关于c++ - 使用C++ OpenMP和文件io进行并行化。性能问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39693557/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com