@@ -196,17 +196,23 @@ void Factorise::processSupernode(Int sn, bool parallelise) {
196196 if (flag_stop_) return ;
197197
198198 if (parallelise) {
199- // spawn children of this supernode in reverse order
200- Int child_to_spawn = first_child_reverse_[sn];
201- while (child_to_spawn != -1 ) {
202- spawnNode (child_to_spawn, tg);
199+ // if there is only one child, do not parallelise
200+ if (first_child_[sn] != -1 && next_child_[first_child_[sn]] == -1 ) {
201+ spawnNode (first_child_[sn], tg, false );
202+ parallelise = false ;
203+ } else {
204+ // spawn children of this supernode in reverse order
205+ Int child_to_spawn = first_child_reverse_[sn];
206+ while (child_to_spawn != -1 ) {
207+ spawnNode (child_to_spawn, tg);
208+
209+ child_to_spawn = next_child_reverse_[child_to_spawn];
210+ }
203211
204- child_to_spawn = next_child_reverse_[child_to_spawn];
212+ // wait for first child to finish, before starting the parent (if there is
213+ // a first child)
214+ if (first_child_[sn] != -1 ) syncNode (first_child_[sn], tg);
205215 }
206-
207- // wait for first child to finish, before starting the parent (if there is a
208- // first child)
209- if (first_child_[sn] != -1 ) syncNode (first_child_[sn], tg);
210216 }
211217
212218#if HIPO_TIMING_LEVEL >= 2
@@ -373,7 +379,11 @@ void Factorise::processSupernode(Int sn, bool parallelise) {
373379#endif
374380}
375381
376- void Factorise::spawnNode (Int sn, const TaskGroupSpecial& tg) {
382+ void Factorise::spawnNode (Int sn, const TaskGroupSpecial& tg, bool do_spawn) {
383+ // if do_spawn is true, a task is actually spawned, otherwise, it is executed
384+ // immediately. This avoids the overhead of spawning a task if a supernode has
385+ // a single child.
386+
377387 auto it = S_.treeSplitting ().find (sn);
378388
379389 if (it == S_.treeSplitting ().end ()) {
@@ -384,15 +394,21 @@ void Factorise::spawnNode(Int sn, const TaskGroupSpecial& tg) {
384394
385395 if (it->second .type == NodeType::single) {
386396 // sn is single node; spawn only that
387- tg.spawn ([this , sn]() { processSupernode (sn, true ); });
397+
398+ auto lambda = [this , sn]() { processSupernode (sn, true ); };
399+
400+ if (do_spawn)
401+ tg.spawn (std::move (lambda));
402+ else
403+ lambda ();
388404
389405 } else {
390406 // sn is head of the first subtree in a group of small subtrees; spawn all
391407 // of them
392408
393409 const NodeData* nd_ptr = &(it->second );
394410
395- tg. spawn ( [this , nd_ptr]() {
411+ auto lambda = [this , nd_ptr]() {
396412 for (Int i = 0 ; i < nd_ptr->group .size (); ++i) {
397413 Int st_head = nd_ptr->group [i];
398414 Int start = nd_ptr->firstdesc [i];
@@ -401,7 +417,12 @@ void Factorise::spawnNode(Int sn, const TaskGroupSpecial& tg) {
401417 processSupernode (sn, false );
402418 }
403419 }
404- });
420+ };
421+
422+ if (do_spawn)
423+ tg.spawn (std::move (lambda));
424+ else
425+ lambda ();
405426 }
406427}
407428
0 commit comments