Nested Async Action Group

I notice that if I have nested async action group constructs, the performance doesn’t improve on multi-core system.

For example,

Main Async Action Group
  Run Action List A (with parameter value A)
  Run Action List A (with parameter value B)
  Run Action List A (with parameter value C)
  Run Action List A (with parameter value D)

Action List A
  Sub Async Action Group
    Task 1
    Task 2
    Task 3
    Task 4

When I run the project, it took about 10 seconds to complete

I then disable async option in “Main Async Action Group”, the duration to complete the project remain the same, 10 seconds.

Disable “Sub Async Action Group” do raise the runtime significantly, which is expected.

Is there any limits or restriction using Async Action Group in nested behavior?


Using Async actions is not a guarantee of better performance. Generally you should use them to perform tasks that do not need the same resources, ie mix i/o bound with cpu/bound. There is an overhead with thread switching, and locking around the logging architecture. We suggest a maximum of 1 thread per core, bearing in mind though that FinalBuilder itself uses threads internally for logging etc. We certainly do not recommend running ascync groups within async groups like you are, you would end up with 20 threads right there… so unless you have around 32 cores and a very fast I/O subsystem you will probably see it slow down.

Threads in windows are not free, there is a cost associated with them (memory, cpu for context switching etc), use sparingly and carefully. FWIW, I once saw a customers project where they were doing what you are, it turned out that they ended up with something like 500 threads and their project was running extremely slowly.

I am that the overhead needed using threads and CPU cores. However, my project design in nested async action group doesn’t fully utilize the CPU computational cycles when running. It use about 50% on a dual core hyperthreading CPU. I hope there are some rooms to run async action nested in another async action.

Most build processes are I/O bound, so unless you are doing some heavy calculations you would struggle to max out your cpus/cores. The more threads you use talking to the same I/O subsystem the worse the performance will get.

What exactly are you doing with the multiple threads. A common thing we see is copying files to multiple servers. The thing is, those multiple threads are probablty communicating with the servers over the same I/O (network connection), it doesn’t take much to max out a network connection with a single thread, so multiple threads will easily max out the network connection, but you would barely see any cpu usage.

I am doing build task for Delphi components in these four actions:
1. Win32, Debug
2. Win32, Release
3. Win64, Debug
4, Win64, Release

Each action will build Delphi components package files (about 300 projects) in parallel and the above actions will run parallel too. So it is a nested async action.