I see suggestions to use ‘make -j$(nproc)’. However, I was taught when learning MPI programming 20 years ago, you want think at least “one to load, one to run”. The idea being that processes and threads waiting on IO will sleep/yield while another process or thread can continue executing. An especially useful strategy if you can afford the RAM (trading RAM for CPU). Consequently, I tend to run twice as many ‘make’ jobs as threads on my systems.