I noticed that my OpenMP-enabled app sometimes only uses 1 thread.
Why?
You may be using OpenCV which turns on OMP_DYNAMIC
, and the GCC libomp
implementation of that depends on the 15-minute load average (a bad idea in my opinion).
This the default implementation of libgomp
OMP_DYNAMIC
/ omp_set_dynamic()
is e.g. on Linux libgomp/config/linux/proc.c
/* When OMP_DYNAMIC is set, at thread launch determine the number of
threads we should spawn for this team. */
/* ??? I have no idea what best practice for this is. Surely some
function of the number of processors that are *still* online and
the load average. Here I use the number of processors online
minus the 15 minute load average. */
unsigned
gomp_dynamic_max_threads (void) {
// ...
return n_onln - loadavg;
OMP_DYNAMIC
is really badNone of this behaviour is documented in libgomp
or the OpenMP spec for OMP_DYNAMIC
.
Those docs sound like the behaviour is nice "runtime-dynamic" when in fact it is fixed across the process's liftime, and based on ultra-slow rolling averages.
In my opinion, somebody should file a GCC bug for this.
Unfortunately the popular OpenCV library turned this on by default in 2018.
This is called at program loading time, as revealed by gdb
:
(gdb) break omp_set_dynamic
Breakpoint 1, 0x00007ffff706c330 in omp_set_dynamic () from /nix/store/7c0yrczwxn58f9gk9ipawdh607vh067k-gcc-12.2.0-lib/lib/libgomp.so.1
(gdb) bt
#0 0x00007ffff706c330 in omp_set_dynamic () from /nix/store/7c0yrczwxn58f9gk9ipawdh607vh067k-gcc-12.2.0-lib/lib/libgomp.so.1
#1 0x00007ffff6c7ed21 in _GLOBAL__sub_I_parallel.cpp () from /nix/store/z2sc2pxysa8shfs9laj0xsmj87qhaq5h-opencv-4.7.0/lib/libopencv_core.so.407
#2 0x00007ffff7fcefae in call_init () from /nix/store/46m4xx889wlhsdj72j38fnlyyvvvvbyb-glibc-2.37-8/lib/ld-linux-x86-64.so.2
#3 0x00007ffff7fcf09c in _dl_init () from /nix/store/46m4xx889wlhsdj72j38fnlyyvvvvbyb-glibc-2.37-8/lib/ld-linux-x86-64.so.2
#4 0x00007ffff7fe4a80 in _dl_start_user () from /nix/store/46m4xx889wlhsdj72j38fnlyyvvvvbyb-glibc-2.37-8/lib/ld-linux-x86-64.so.2
So if your app dynamically links against OpenCV, this happens.
I filed a bug to disable it: https://github.com/opencv/opencv/issues/25717
Set the environment variable
OPENCV_FOR_OPENMP_DYNAMIC_DISABLE=1 yourprogram...