我尝试做的是立即生成N
个任务,通过在任务的帮助下递归划分迭代空间,以便产生真实的'任务更快。
我可以使用循环线性地执行此操作,如下所示:
for (int i = 0; i < N; i+=bx)
#pragma omp task firstprivate(i)
task_work(i);
以下是我目前在递归版本中所获得的内容。
void rec_spawn(int start, int end, int cz)
{
// If the iteration space lower than the chunksize 'cz', spawn the tasks
// linearly. Otherwise divide the iteration space in two, and call this
// function recursively.
if (end - start <= cz)
{
for (int ii=start_outer; ii < end_outer; ii+=bx)
#pragma omp task firstprivate(ii)
task_work(ii)
}
else
{
// first half
#pragma omp task firstprivate(start, end, cz)
rec_spawn(start, start + ((end - start) / 2), cz);
// second half
#pragma omp task firstprivate(start, end, cz)
rec_spawn(start + ((end - start) / 2), end, cz);
}
#pragma omp taskwait
}
这个版本慢得多,它不应该是,我怀疑它是由#pragma omp taskwait
引起的。我希望能够做类似的事情,但没有任务等待,但是当我尝试删除代码段错误。
当我尝试调试程序时,我可以收集的所有信息是:
Program terminated with signal 11, Segmentation fault.
#0 0x00000000004057de in gomp_barrier_handle_tasks (state=<optimized out>) at ../../../gcc-4.9.0/libgomp/task.c:715
715 ../../../gcc-4.9.0/libgomp/task.c: No such file or directory.
(gdb) bt
#0 0x00000000004057de in gomp_barrier_handle_tasks (state=<optimized out>) at ../../../gcc-4.9.0/libgomp/task.c:715
#1 0x0000000000409518 in gomp_team_barrier_wait_end (bar=0x11a2874, state=0) at ../../../gcc-4.9.0/libgomp/config/linux/bar.c:94
#2 0x0000000000401d24 in main._omp_fn.0 () at src/heat-omp-rec.c:86
#3 0x000000000040705e in gomp_barrier_init (count=<optimized out>, bar=<optimized out>) at ../../../gcc-4.9.0/libgomp/config/linux/bar.h:59
#4 gomp_new_team (nthreads=4201738) at ../../../gcc-4.9.0/libgomp/team.c:166
#5 0x00007fff7d208d50 in ?? ()
#6 0x00007f7080cb69c0 in ?? ()
#7 0x0000000000000000 in ?? ()
所以我的问题是,为什么这里需要taskwait(task_work()中的实际工作不需要),以及如何重写递归产生而不使用它。