我已经四处找了好几天了,我找不到对我的问题的解释(因此也找不到解决方法)。
我有一个数百万行的文件,我想独立处理。每行表示一个对象,我在其上调用一个函数,其执行时间取决于对象本身的某些属性。执行时间不平衡,在某些情况下可能需要不到一秒钟,或者几分钟或几小时。
我用while循环解析文件,并使用任务:
ifstream fin(FileName);
#pragma omp parallel num_threads(N)
{
#pragma omp single
{
string line;
#pragma omp task untied
while (getline(fin, line)) {
#pragma omp task firstprivate(line)
function(line);
}
}
}
我观察到的是,有时一些线程会被挂起,比如如果任务池是空的,它们会等待新任务的创建。我注意到我已经到了除了一个线程之外的所有线程都被挂起的地步,一旦这个线程结束执行它的任务,它们都会重新开始运行。在我的第一个版本中,我没有使用未绑定子句,我认为问题可能是读取文件的线程(比如线程0)正忙于执行一个长任务本身,无法继续读取文件和创建新任务。但是,添加未绑定子句(以便任何其他线程都可以继续读取文件)并不能解决问题。
我有一些问题:
如果任务的数量远远大于池大小(我理解为64*number_of_threads),那么线程0是否会暂停其当前任务(即读取文件并生成新任务)并帮助其他线程执行任务?我通常读到,当它结束创建任务时,它会帮助其他线程(例如:omp single和omp task如何提供并行性),但我觉得这不是我的情况。
无条件条款是否符合我的预期?也就是说,如果线程0忙于执行任务,那么另一个线程可以继续读取文件并填充任务池?如果这是真的,为什么我看到线程不做任何事情?
是否存在阻碍任何线程继续读取文件并创建新任务直到池为空的障碍?我希望当线程看到任务池为空时,它会用新任务填充它。即使一个线程只用于在另一个线程从池中选择任务时读取新行,我也会很高兴。
感谢任何建议!
在期间删除之前的任务。一个典型的习惯用法是,一个线程(来自并行/单线程)生成所有任务,其他线程将它们从内部任务队列中移除。因此,while循环应该由线程执行,而不是在任务中执行。然后,它将生成与您的行相对应的任务,供其他线程执行。