diff options
Diffstat (limited to 'intern/cycles/device/opencl/opencl_util.cpp')
-rw-r--r-- | intern/cycles/device/opencl/opencl_util.cpp | 35 |
1 files changed, 32 insertions, 3 deletions
diff --git a/intern/cycles/device/opencl/opencl_util.cpp b/intern/cycles/device/opencl/opencl_util.cpp index 978c75d2e2c..b8b07cf2947 100644 --- a/intern/cycles/device/opencl/opencl_util.cpp +++ b/intern/cycles/device/opencl/opencl_util.cpp @@ -23,6 +23,7 @@ # include "util/util_logging.h" # include "util/util_md5.h" # include "util/util_path.h" +# include "util/util_semaphore.h" # include "util/util_system.h" # include "util/util_time.h" @@ -390,8 +391,27 @@ static void escape_python_string(string &str) string_replace(str, "'", "\'"); } +static int opencl_compile_process_limit() +{ + /* Limit number of concurrent processes compiling, with a heuristic based + * on total physical RAM and estimate of memory usage needed when compiling + * with all Cycles features enabled. + * + * This is somewhat arbitrary as we don't know the actual available RAM or + * how much the kernel compilation will needed depending on the features, but + * better than not limiting at all. */ + static const int64_t GB = 1024LL * 1024LL * 1024LL; + static const int64_t process_memory = 2 * GB; + static const int64_t base_memory = 2 * GB; + static const int64_t system_memory = system_physical_ram(); + static const int64_t process_limit = (system_memory - base_memory) / process_memory; + + return max((int)process_limit, 1); +} + bool OpenCLDevice::OpenCLProgram::compile_separate(const string &clbin) { + /* Construct arguments. */ vector<string> args; args.push_back("--background"); args.push_back("--factory-startup"); @@ -419,14 +439,23 @@ bool OpenCLDevice::OpenCLProgram::compile_separate(const string &clbin) kernel_file_escaped.c_str(), clbin_escaped.c_str())); - double starttime = time_dt(); + /* Limit number of concurrent processes compiling. */ + static thread_counting_semaphore semaphore(opencl_compile_process_limit()); + semaphore.acquire(); + + /* Compile. */ + const double starttime = time_dt(); add_log(string("Cycles: compiling OpenCL program ") + program_name + "...", false); add_log(string("Build flags: ") + kernel_build_options, true); - if (!system_call_self(args) || !path_exists(clbin)) { + const bool success = system_call_self(args); + const double elapsed = time_dt() - starttime; + + semaphore.release(); + + if (!success || !path_exists(clbin)) { return false; } - double elapsed = time_dt() - starttime; add_log( string_printf("Kernel compilation of %s finished in %.2lfs.", program_name.c_str(), elapsed), false); |