我有一个循环,我使用 OpenMP 将其并行化。在这个循环中,我从文件中读取一个三角形,并对这些数据执行一些操作。这些操作独立于每个三角形到另一个三角形,所以我认为这很容易并行化,只要我将文件的实际读取保持在关键部分。
- 读取三角形的顺序并不重要
- 一些三角形被读取并很快被丢弃,一些需要更多的算法工作(bbox 构造,...)
- 我在做二进制 I/O
- 使用 C++ ifstream *tri_data*
- 我在 SSD 上测试这个
ReadTriangle 调用 file.read() 并从 ifstream 中读取 12 个浮点数。
#pragma omp parallel for shared (tri_data)
for(int i = 0; i < ntriangles ; i++) {
vec3 v0,v1,v2,normal;
#pragma omp critical
{
readTriangle(tri_data,v0,v1,v2,normal);
}
(working with the triangle here)
}
现在,我观察到的行为是启用 OpenMP 后,整个过程会变慢。我在代码中添加了一些计时器来跟踪在 I/O 方法中花费的时间,以及在循环本身中花费的时间。
没有 OpenMP:
Total IO IN time : 41.836 s.
Total algorithm time : 15.495 s.
使用 OpenMP:
Total IO IN time : 48.959 s.
Total algorithm time : 44.61 s.
我的猜测是,由于读取处于临界区,线程只是在等待彼此完成使用文件处理程序,导致等待时间更长。
有关如何解决此问题的任何指示?我的程序将真正受益于处理具有多个进程的读取三角形的可能性。我试过玩弄线程调度和相关的东西,但这在这种情况下似乎没有多大帮助。
由于我正在研究核外算法,因此引入缓冲区来容纳大量三角形并不是一个真正的选择。