-
Notifications
You must be signed in to change notification settings - Fork 10.6k
[update-checkout] lower the default number of parallel processes #84081
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
base: main
Are you sure you want to change the base?
[update-checkout] lower the default number of parallel processes #84081
Conversation
@swift-ci please test |
0779d65
to
e56f838
Compare
@swift-ci please smoke test |
e56f838
to
b944d52
Compare
@swift-ci please smoke test |
parallel implementation. | ||
""" | ||
|
||
# On Windows, the underlying implementation of Pool only supports up to 64 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is misleading. WFMO is limited to MAXIMUM_WAIT_OBJECTS
. You can use RegisterWaitForObject
or an IOCP. This is just a QoI issue, not a windows specific issue. Did you compare this to the implementation in CPython? You should bind it to the version if they are using a specific implementation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you compare this to the implementation in CPython?
concurrent/futures
documents this limit: https://github.com/python/cpython/blob/424e2ab95a0b225effa4ec1057be467bf696f75e/Lib/concurrent/futures/process.py#L121-L122
multiprocessing
seems to be using WaitForMultipleObjectsEx
: https://github.com/python/cpython/blob/424e2ab95a0b225effa4ec1057be467bf696f75e/Modules/_multiprocessing/semaphore.c#L154
This is just a QoI issue, not a windows specific issue.
I have only encountered this issue on Windows and my fix is specifically tailored towards Windows.
This is misleading.
I'm happy to rephrase the comment with something more generic like: "Cap the number of processes to 60
to stay below the limit allowed by some platforms."
The end goal of this patch is to improve the Qol of update-checkout
. Refactoring the code to support more than 60 processes does not seem like it's worth it, compared to just capping the value.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I meant that this is a QoI issue with python. I think that the comment would be better phrased as:
Workaround a limitation of Python's implementation of threading. The CPython implementation uses `WaitForSingleObject` which is bound by `MAXIMUM_WAIT_OBJECTS` rather than using `RegisterWaitForObject` or an I/O completion port. In order to ensure that we do not exceed that limit, bound the number of parallel jobs to 60.
I think that additionally, we should use something like:
import win32event
kMaximumThreads = win32event.MAXIMUM_WAIT_OBJECTS - 4
rather than the embedded 60.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I meant that this is a QoI issue with python.
I see, thanks for the clarification! I changed the comment to your suggestion.
I think that additionally, we should use something like:
import win32event kMaximumThreads = win32event.MAXIMUM_WAIT_OBJECTS - 4rather than the embedded 60.
Since win32event is not bundled with Python, I think it's best not to add a mandatory dependency to update-checkout
. This would require adapting the CI script on Windows. I think it's fine to hardcode 60
, as there are far fewer than 60 repositories anyways.
It's possible that a user has a version of Windows where MAXIMUM_WAIT_OBJECTS
is set to something lower than 60
but that seems like a very rare edge case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We do seem to be growing the number of repositories that we need to checkout to build, so it feels like we should just grow this dependency if we want to go with update-checkout instead of repo.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's see the pros/cons of both approaches:
A. Hardcoding 60:
Pros
- Small patch
Cons
- Might yield slower clone time (if we have more than 60 repos, we currently have 50). This might not even be true as
llvm-project
is the longest to clone and is almost always the limiting factor when cloning all the repositories.
B. Using win32events
Pros
- No hardcoded value. Can be updated if
MAXIMUM_WAIT_OBJECTS
changes value.
Cons
- Need to install a dependency to run
update-checkout
. This requires editing the CI scripts for all platforms.
If I did not miss anything, I think the cons vastly overweight the pros in approach B. It's not clear to me why requiring a dependency to run update-checkout
is worth (eventually) cloning more than 60
repositories in parallel.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've just hit this problem myself, so I have some thoughts here :-)
Let's not add a dependency on win32event
here. That just adds a lot of extra work for what is a fairly minor fix.
I agree with @adrian-prantl that 60 is in any case way more than we need. I suspect it's pointless going much higher than 16 at a time — the performance gains from being more parallel than that likely tail off very quickly, and additionally trying to simultaneously clone 60 repos might even be seen as abusive (though GitHub is big and will probably cope).
b944d52
to
0b6955d
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Even 60 seems to be very high to me, but generally limiting makes sense.
@swift-ci please test |
@swift-ci please smoke test macOS |
@swift-ci please test macOS |
1 similar comment
@swift-ci please test macOS |
Hi @compnerd, is there anything else I should change on this PR in order to merge it? Regarding #84081 (comment), I still think we should avoid adding another dependecy to building Swift on Windows, with the |
I think that it is a reasonable dependency to add; if we are going to grow our own homebrew tools, then we need to start considering the cost of the additional dependencies to get the things to work properly. The better solution IMO is to just switch to repo. |
My concern is that update-checkout does not have any dependencies at the moment. Adding an external dependency would mean adding a I don't think this extra complexity is worth it for this simple Windows specific patch. |
Agreed, let's set it to a smaller number. 60 at once is unnecessary and unlikely to genuinely be any faster than (say) working 16 at a time. |
0b6955d
to
76e2c07
Compare
Since the maximum number of parallel processes should depend on the number of CPU cores, I have lowered the default value to |
|
74860e0
to
8a4a69d
Compare
@swift-ci please smoke test |
8a4a69d
to
ea2e2e8
Compare
ea2e2e8
to
7a09a93
Compare
@swift-ci please smoke test |
This patch lowers the default number of parallel processes from
os.cpu_count() * 2
toos.cpu_count()
.This has the side effect of fixing an issue on Windows on systems with >= 16 CPU cores:
The implementation of
multiprocessing.Pool
in Python usesWaitForMultipleObjects
on Windows. The maximum value of processes this function can take is capped byMAXIMUM_WAIT_OBJECTS
, which is 64.This avoids
Pool
to throw on Windows on systems with a high number of CPU cores (a 16 cores CPU will encounter this error).rdar://159749646