-
Notifications
You must be signed in to change notification settings - Fork 18k
cmd/go: build the cgo artifacts for each package in parallel #9887
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
Comments
Seems reasonable to me. Why not send the patch? |
CL https://golang.org/cl/4931 mentions this issue. |
I'm curious if there is any plan to parallelize cgo compilation for go1.7. The finer-grained work scheduling for go tool actions mentioned in https://go-review.googlesource.com/#/c/4931/ would be great if it ever happens, though it doesn't look like there is any movement on that front. |
Contrast #21605. Are there any similar ordering issues for other languages? |
Currently we only support C, C++, and Fortran, and C and C++ have no ordering issues. I'm not aware of ordering issues for any other language. |
Any updates on this? Compiling one of our packages takes around 30 seconds... |
I had a brief look at this last week, because this is causing an annoying build time bottleneck in a project of mine. I assume the file we're interested in is In particular, the It's unclear to me how we'd fix this, though. Can anyone point me to a doc that explains how For example, I can imagine these ways to fix the issue, but it's unclear which would be the right one:
|
I had a sudden realisation: one of the packages that are really slow to compile with cgo, https://github.com/olebedev/go-duktape/tree/v3, simply bundles a ton of C code as a single 3.5MiB file. I presume that parallelizing cgo compilation per-file wouldn't help at all in that case, and I also assume that there is no way to make that any faster. Luckily, that's not the norm. For example, https://github.com/ipsn/go-libtor builds tor from its C source, directly building its thousands of C files. That seems like it would get a big win from a fix for this issue. |
From my observation, both I was able to write a prototype that attempts to parallelize both of them, If anybody wants to test how much faster the changes are, it can be found at I'm currently daily driving Go 1.17 with these 2 patches applied on top almost The branch doesn't account for Fortran, however, so it might not work at all for |
@diamondburned thanks for the info. I am currently testing your patch ( Edit: I tested the patch with our cgo-based project and the build acceleration is enormous. Thanks!
@bcmills The linked issue has been deprioritized by @rsc @rsc willing to include the patch from @diamondburned ? Edit 2: |
Just as a small update, branch go-cgo-gcc-parallelism-1.18 now tracks the 2 patches for Go 1.18. For Nix users, the drop-in overlay is (self: super: {
go = super.go.overrideAttrs (old: {
version = "1.18";
src = builtins.fetchurl {
url = "https://golang.org/dl/go1.18.linux-amd64.tar.gz";
sha256 = "0kr6h1ddaazibxfkmw7b7jqyqhskvzjyc2c4zr8b3kapizlphlp8";
};
doCheck = false;
patches = [
# cmd/go/internal/work: concurrent ccompile routines
(builtins.fetchurl "https://github.com/diamondburned/go/commit/ec3e1c9471f170187b6a7c83ab0364253f895c28.patch")
# cmd/cgo: concurrent file generation
(builtins.fetchurl "https://github.com/diamondburned/go/commit/50e04befeca9ae63296a73c8d5d2870b904971b4.patch")
];
});
}) |
@diamondburned Unfortunately your code have problems. When attempting to compile my project with your version, it failed with a rather cryptic error:
I used this branch: https://github.com/diamondburned/go/tree/go-cgo-gcc-parallelism-1.18 |
The modifications are definitely band-aid. It works for my purposes so I've stopped there, because If you can't get the compiler to work with just the |
I've made go-cgo-gcc-parallelism-1.19 to track Go 1.19. |
https://github.com/Evengard/go/tree/go-cgo-gcc-parallelism-1.20.3 tracks the Go 1.20.3 release for anyone who needs that. |
It's been a while since this issue was created and two CLs were abandoned in favor to properly redesign This is definetely rught thing to do, but nobody had time to implement that. Are we happy to do a tiny fix to just parallelize the work inside |
Change https://go.dev/cl/579815 mentions this issue: |
I've tried to keep it as less invasive as possible, let me know if it works for you |
It would be ideal to try to fix this by making actions more fine grained, especially since there aren't any other cases where we do work concurrently within an action. It complicates to have two layers of concurrency- one layer being the actions that are running and the other being the C compilations within the action. |
AFAIK, this was one of the reasons for not merging the CLs. I definitely agree that that's the ideal solution, but as @podtserkovskiy pointed out, it wasn't really being worked on, unfortunately. |
I fully agree that the redesign of the actions API would be ideal, but this is not a trivial change and it requires much more time for proper implementation than this fix.
I can recall one more place with a potential to execute things concurrently |
Sorry, I meant that there aren't any other places currently where we do work concurrently with an action |
hi @podtserkovskiy , I've tried out your change on cimgui-go repository [examples (130) ]$ time ~/git/go/bin/go build .
real 3m19.036s
user 3m39.633s
sys 0m4.831s
[examples (0) ]$ time go build -a .
real 3m30.830s
user 3m46.801s
sys 0m6.414s
[examples (0) ]$ [examples (0) ]$ ~/git/go/bin/go version # with applied patch
go version devel go1.23-fe5487327a Tue Apr 23 08:28:17 2024 +0200 linux/amd64 |
Yeah, unfortunately, |
BTW, I've tried to do a quick experiment with |
I've published parallelisation of There are more But even this change makes processing of "net" package (5 CGo files) 25% faster. |
Hi, I have a very large CGO module. The /qt/ package alone has 340 .cpp files plus 340 .go files using CGO. Some tests on a 4-core Neoverse N1:
|
The lack of parallelization for compilations within a single package doesn't matter too much when building go files, but does affect cgo compilation. I have a package with about 32k lines of (generated) C++. Compiling it serially takes ~10.5s. A small hack to cmd/go/build.go to compile C/C++/Obj-C files in parallel brings this down to ~3.7s.
The patch I hacked together to parallelize cgo compilation work is ~50 lines of deltas and is mostly contained in
builder.cgo()
.PS The compilation times above were measured using go 1.4.1 on Mac OS X, but this code hasn't changed at head and similar compilation times can be seen there.
The text was updated successfully, but these errors were encountered: