-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Use a thread pool when building runtimes #6133
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
cd5b7b7
a732ec4
40f5e61
df546ea
cc7cb77
94370ce
1f90e49
13289a2
5fbb837
1833476
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -32,6 +32,7 @@ struct Options { | |
| bool verbose = false; | ||
| bool fuzzing = false; | ||
| bool include_diagnostic_kind = false; | ||
| bool threads = true; | ||
|
|
||
| llvm::StringRef runtimes_cache_path; | ||
| llvm::StringRef prebuilt_runtimes_path; | ||
|
|
@@ -124,6 +125,25 @@ applies to each message that forms a diagnostic, not just the primary message. | |
| }, | ||
| [&](auto& arg_b) { arg_b.Set(&include_diagnostic_kind); }); | ||
|
|
||
| b.AddFlag( | ||
| { | ||
| .name = "threads", | ||
| .help = R"""( | ||
| Controls whether threads are used to build runtimes. | ||
|
|
||
| When enabled (the default), Carbon will try to build runtime libraries using | ||
| threads to parallelize the operation. How many threads is controlled | ||
| automatically by the system. | ||
|
|
||
| Disabling threads ensures a single threaded build of the runtimes which can help | ||
| when there are errors or other output. | ||
| )""", | ||
| }, | ||
| [&](auto& arg_b) { | ||
| arg_b.Default(true); | ||
| arg_b.Set(&threads); | ||
| }); | ||
|
|
||
| runtimes.AddTo(b, &selected_subcommand); | ||
| clang.AddTo(b, &selected_subcommand); | ||
| compile.AddTo(b, &selected_subcommand); | ||
|
|
@@ -208,6 +228,14 @@ auto Driver::RunCommand(llvm::ArrayRef<llvm::StringRef> args) -> DriverResult { | |
| driver_env_.fuzzing = true; | ||
| } | ||
|
|
||
| llvm::SingleThreadExecutor single_thread({.ThreadsRequested = 1}); | ||
| std::optional<llvm::DefaultThreadPool> threads; | ||
| driver_env_.thread_pool = &single_thread; | ||
| if (options.threads) { | ||
| threads.emplace(llvm::optimal_concurrency()); | ||
| driver_env_.thread_pool = &*threads; | ||
| } | ||
|
Comment on lines
+231
to
+237
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We're are creating this SingleThreadExecutor at multiple levels it seems, both here and inside the ClangRunner. Could we consolidate to a single place - maybe making ClangRunner expect to receive a non-null executor always? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We could... I was just a bit torn doing so as it adds quite a bit of complexity to building and using the runner which is only needed if you're actually building runtimes. Another alternative would be to have There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do you forsee wanting to use other thread pools than SingleThreadExecutor and DefaultThreadPool? Maybe we could tell it if we want threads or not and have ClangRunner make what it needs? Taking either a path XOR a thread pool also sounds good, whichever you pref There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Some possibility. One thing I wonder is if we'll want a (much) larger thread pool to fully absorb the latency, but would like to avoid it given the overhead.
When using threads, my expectation is that it'll be very desirable to use the existing thread pool to avoid paying the cost of spinning one up and forking all the threads. It also allows more global management of the load. This is why I somewhat like the driver either accepting or building a thread pool, and then making it available for any commands or subcommands to use.
I think what I'm liking is to take one of:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually, I thought more about this and I think I had the fundamental wrong structure of this API. I've restructured everything so that we have a simple constructor that only accepts the necessary components. Then there are three variations on |
||
|
|
||
| CARBON_CHECK(options.selected_subcommand != nullptr); | ||
| return options.selected_subcommand->Run(driver_env_); | ||
| } | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.