diff --git a/NEWS.md b/NEWS.md index c349122b6..b53530d8f 100644 --- a/NEWS.md +++ b/NEWS.md @@ -21,6 +21,9 @@ (#900). - Fixed a crash when branch coverage is enabled and an if-statement contains a `return` (#903). +- The `NVC_CONCURRENT_JOBS` environment variable can be used to scale + the number of worker threads NVC creates based on the number of + concurrently executing simulations. ## Version 1.12.2 - 2024-05-15 - Fixed a crash when `'transaction` is used with a record type. diff --git a/nvc.1 b/nvc.1 index 43f140bee..632a322c3 100644 --- a/nvc.1 +++ b/nvc.1 @@ -1162,7 +1162,15 @@ arguments. Additionally foreign subprograms must not retain any pointers passed as arguments after the subprogram returns. Violating these rules will result in unpredictable and hard to debug behaviour. .Sh ENVIRONMENT -.Bl -tag -width "NVC_COLORS" +.Bl -tag -width "NVC_CONCURRENT_JOBS" +.It Ev NVC_CONCURRENT_JOBS +Provides a hint for the number of concurrently executing simulations. +This allows +.Nm +to scale its worker thread count to avoid overloading the system. +This is set automatically by frameworks such as VUnit. +See +.Ev NVC_MAX_THREADS . .It Ev NVC_COLORS Controls whether .Nm @@ -1175,6 +1183,12 @@ and which enables colour if stdout is connected to a terminal. The default is .Cm auto . +.It Ev NVC_MAX_THREADS +Limit the number of worker threads +.Nm +can create. +The default is either eight or the number of available CPUs, whichever +is smaller. .El .\" .Sh FILES .\" .Sh EXIT STATUS diff --git a/src/thread.c b/src/thread.c index 71b7b4858..bed019e7a 100644 --- a/src/thread.c +++ b/src/thread.c @@ -23,6 +23,7 @@ #include #include +#include #include #include #include @@ -498,11 +499,22 @@ void thread_init(void) assert(my_thread->id == 0); - const char *env = getenv("NVC_MAX_THREADS"); - if (env != NULL) - max_workers = MAX(1, MIN(atoi(env), MAX_THREADS)); + const char *max_env = getenv("NVC_MAX_THREADS"); + if (max_env != NULL) + max_workers = MAX(1, MIN(atoi(max_env), MAX_THREADS)); else - max_workers = MIN(nvc_nprocs(), DEFAULT_THREADS); + max_workers = DEFAULT_THREADS; + + const int num_cpus = nvc_nprocs(); + max_workers = MIN(num_cpus, max_workers); + + const char *jobs_env = getenv("NVC_CONCURRENT_JOBS"); + if (jobs_env != NULL) { + const int num_jobs = MAX(1, atoi(jobs_env)); + const int limit = (int)round((double)num_cpus / (double)num_jobs); + max_workers = MAX(1, MIN(max_workers, limit)); + } + assert(max_workers > 0); #ifdef DEBUG