-
Notifications
You must be signed in to change notification settings - Fork 417
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
run analyzers on multiple threads if allowed to #2285
Conversation
there is now a new option in the roslyn-extensions-option: ThreadsToUseForAnalyzers - which defaults to half the number of processors on the machine. there are two workers started, one for background and one for foreground. so this *might* actually use all the cores? in my usage it seems not to.
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.
Seems like a simple solution, I think it might work. When I did my quick hack however I did get some timeout errors, have you noticed anything like that? I probably got timeouts because I was going full blast with no "throttler" though.
Also, there's a similar foreach loop here, do you think it might need the same treatment?
omnisharp-roslyn/src/OmniSharp.Roslyn.CSharp/Workers/Diagnostics/CSharpDiagnosticWorker.cs
Lines 149 to 157 in 6a5ccc4
foreach (var document in documents) | |
{ | |
if (document?.Project?.Name == null) | |
continue; | |
var projectName = document.Project.Name; | |
var diagnostics = await GetDiagnosticsForDocument(document, projectName); | |
results.Add(new DocumentDiagnostics(document.Id, document.FilePath, document.Project.Id, document.Project.Name, diagnostics)); | |
} |
Co-authored-by: David Zidar <[email protected]>
nice catch, I'll look into it |
same logic as for the diagnostic worker with analyzers.
since it's used for diagnostic with and without analyzers the name should reflect this
I just pulled your branch and tried it out and it is indeed much faster, but I'm still getting the timeout errors I mentioned and tested this on a small/medium sized project on a 16 core Ryzen 5950X. They look like this in the OmniSharp log (I truncated the list of analyzers because it is very long):
The timeout seems to be this one which is only 10 seconds, I'm thinking the default value would have to be increased when running things in parallel. Maybe 30 seconds?
|
ah, I've had that at 30 seconds for a long time, that's probably why I wasn't seeing the timeouts. is there a problem if we just increase the default to that? |
i've set it to 30s default. |
i should never try to do this stuff from github
- Parallelize at the document level instead of only at the project level (so user benefits also with few projects but many files) - Since currently analyzing project no longer has any real meaning, add new status events to convey "analyzing n remaining files", updates every 50 documents - Retain old status events for backward compat with clients - Use 75% of available cores instead of half
I opened an alternative PR #2312 with some further improvements upon this work. |
hard-coding to a number of documents (e.g. 50 or 24) will either send updates very rarely giving large jumps, or very frequently (i.e. many times within one percentage-point). this change calculates how many documents correspond to 1%, and send an event every time that has been reached. if that is less than every 10 documents, it events on every tenth document. this avoids unnecessary updates and updates as often as relevant.
can we get a review on this @filipw or someone with write access? just picked filip to mention as he's the top contributor and probably know who would be right. |
@TomasEkeli Can you update the PR description to describe the changes the code is currently making. I didn't see a new RoslynOption for number of analyzer threads for instance. There are certainly multiple places we could add parallelism to the Analyzer runner. In |
i've updated the pull-request description, @JoeRobich - it was a little outdated. sorry about that, and i hope it's clearer now. |
@JoeRobich We did consider setting
Not sure if that's applicable at all in the OmniSharp context given that it's in a separate process from the IDE, but decided not the risk it nonetheless. |
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.
Thanks!
CC: @filipw, in case you have any concerns |
I think this should be OK because it is gated. Also, normally we hide such features behind feature flags, but since the entire analysis is behind a feature flag already, it is fine. I am a bit worried that it can lead to state corruption on the client side but we can give it a try. Thanks a lot for your work. |
i'v updated the wiki |
Unfortunately, looking at the feedback in dotnet/vscode-csharp#5017 from users using the latest build from master, it seems like there is indeed a regression where diagnostics retrieval crashes with a null reference. |
@filipw I can take a look later tonight. What's the correct process here, open another PR against |
thanks, yes that is correct. Every merge to master is published as beta prerelease and users who have |
@DavidZidar Yep, that's the same improvement I had previously made in the Anyway, kudos for tracking it down and fixing! 👍🏻 |
@DaRosenberg Ah, and a good improvement it was. :) I reviewed the code at the time but failed to consider concurrency. And thanks for the initial investigation on how to reproduce the issue, it really helped! |
fixes #2241
background
running analyzers is is currently sequential and can take a long time on big projects. this change can help by running
in parallel, particularly if the machine has many cores.
configuration
introduces a new option the user can set in
omnisharp.json
:RoslynExtensionsOptions.DiagnosticWorkersThreadCount
.observability
the analysers report their status as a percentage done of the total number of documents to analyse. this is done instead of listing the currently analysed project, and gives the user a better experience. thanks to @DaRosenberg for this, and help throughout!
in my experience this decreases the wall-time of analysers by a good amount at the expense of running the users' computer hotter. exposing it as a configuration allows the users to make their own trade-off.
documentation
the documentation for
omnisharp.json
in the wiki should be updated once this is merged.