我有一个循环,我使用OpenMP进行并行化。在这个循环中,我从文件中读取一个三角形,并对该数据执行一些操作。这些操作从每个三角形到另一个三角形是独立的,所以我认为这很容易并行化,只要我在关键部分保持实际读取文件。
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.
我的猜测是,由于读取位于关键部分,因此线程只是在等待彼此完成使用文件处理程序,从而导致更长的等待时间。
有关如何解决此问题的任何指示?我的程序将真正受益于处理具有多个进程的读取三角形的可能性。我尝试过使用线程调度和相关的东西,但在这种情况下,这似乎没什么帮助。
由于我正在研究一种核外算法,因此引入缓冲区来容纳多个三角形并不是一种选择。
答案 0 :(得分:1)
所以,我建议的解决方案是基于主/从策略,其中:
伪代码将读取如下内容:
#include<omp.h>
vector<vec3> v0;
vector<vec3> v1;
vector<vec3> v2;
vector<vec3> normal;
vector<int> tdone;
int nthreads;
int triangles_read = 0;
/* ... */
#pragma omp parallel shared(tri_data)
{
int id = omp_get_thread_num();
/*
* Initialize all the buffers in the master thread.
* Notice that the size in memory is similar to your example.
*/
#pragma omp single
{
nthreads = omp_get_num_threads();
v0.resize(nthreads);
v1.resize(nthreads);
v2.resize(nthreads);
normal.resize(nthreads);
tdone.resize(nthreads,1);
}
if ( id == 0 ) { // Producer thread
int next = 1;
while( triangles_read != ntriangles ) {
if ( tdone[next] ) { // If the next thread is free
readTriangle(tri_data,v0[next],v1[next],v2[next],normal[next]); // Read data and fill the correct buffer
triangles_read++;
tdone[next] = 0; // Set a flag for thread next to start working
#pragma omp flush (tdone[next],triangles_read) // Flush it
}
next = next%(nthreads - 1) + 1; // Set next
} // while
} else { // Consumer threads
while( true ) { // Wait for work
if( tdone[id] == 0) {
/* ... do work here on v0[id], v1[id], v2[id], normal[id] ... */
tdone[id] == 1;
#pragma omp flush (tdone[id]) // Flush it
}
if( tdone[id] == 1 && triangles_read == ntriangles) break; // Work finished for all
}
}
#pragma omp barrier
}
我不确定这对你是否仍然有价值,但无论如何这是一个很好的预告片!