Re: GCC optimization and speedup capabilities

Heime via Gcc-help <[email protected]> Wed, 20 May 2026 07:37:11 +0000
Newsgroups gmane.comp.gcc.help
Message-ID <YCb_taC4i7i7RgRQJulZ3V7kKSUj1CpqDa5qMoQX3uK-EFL6lH0mJ3bnJOxCxLtiJmtzSyCH6CeumGvWOsOADKOj1dSIhyjPQisJl3rPlgM=@protonmail.com>

On Wednesday, May 20th, 2026 at 3:13 PM, Simon Richter <Simon.Richter@hogyr=
os.de> wrote:

> Hi,
>
> On 5/20/26 07:41, Heime via Gcc-help wrote:
>
> > GCC can add optimisations for a program automatically.  Is it capable
> > of taking advantage of multiple threads and available cores, without
> > the developer having to code them on a single machine?
>
> There is OpenMP, which allows using an attribute-like syntax on a loop
> to indicate that it should be parallelized across multiple threads.
>
> This does require programmer action to specify which loop, but very
> little other code changes, so it can be used for some quick gains.
>
> This is generally only worth it if your program has some loop that runs
> for a long time and where each iteration is not dependent on a previous
> one. Those kind of workloads are also usually suitable for GPUs, so you
> will find that rather few people use OpenMP, and instead switch to
> OpenCL, Vulkan, or one of the vendor APIs.
>
> In an abstract way, loop optimizations turn one loop into nested loops li=
ke
>
>      for(int i =3D 0; i < count; ++i)
>
> becomes
>
>      for(int l =3D 0; l < count; l +=3D unroll*batch*nproc)
>          // run this on "nproc" different CPUs in parallel
>          for(int k =3D l; k < l + unroll*batch*nproc; atomic_add(k,
> unroll*batch))
>              for(int j =3D k; j < k + unroll*batch; j +=3D unroll)
>                  for(int i =3D j; i < j + unroll; ++i)
>                      if(i < count)
>
> where we select "unroll" so that the number of registers used in the
> inner loop, times "unroll", is smaller than the number of CPU registers
> available. That is information we have available at compile time, and
> especially if we can use SIMD instructions and registers, that number
> can easily go to 16 or 32.
>
> "count" and "nproc" on the other hand, are runtime parameters, so we
> cannot anticipate them, and "batch" is a performance tuning parameter
> (small batches mean more calls to atomic_add to synchronize with other
> cores, large batches mean that workloads can get unbalanced).
>
> The normal loop optimizations assume that "nproc" and "batch" are 1,
> because it is not known if "count" is large enough that starting
> additional threads is worth it, and "batch" only becomes relevant if
> there is parallel processing.
>
> In principle, these values could be derived from profiling information,
> while in practice the remaining users that have not switched to GPU
> computation (e.g. because their workload is GPU hostile) prefer to
> either write an explicit job scheduler, or specify the values via OpenMP.
>
> So yes, there is some support, but unlike unrolling the inner loop, the
> optimal choice for distributing workloads across multiple threads
> depends on runtime parameters, so additional information is needed
> before those optimizations can be applied, and very few workloads
> qualify, so this is not enabled by default.
>
>     Simon

If multithreading is a type of concurrency - threads cannot=20
overlap - how was I able to make computations go faster=20
nevertheless in a fortran program?