Skip to content
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

WriteCharsLegacy performance issues caused by NotifyConsoleUpdateSimpleEvent #10528

Open
skyline75489 opened this issue Jun 29, 2021 · 19 comments
Labels
Area-Performance Performance-related issue Help Wanted We encourage anyone to jump in on these. Issue-Task It's a feature request, but it doesn't really need a major design. Product-Conhost For issues in the Console codebase
Milestone

Comments

@skyline75489
Copy link
Collaborator

Description of the new feature/enhancement

I know this is a issue a long time ago, but haven't got the chance to talk about it.

This is typical WPR trace of OpenConsole with output-heavy programs.

image

Proposed technical implementation details (optional)

Perhaps throttling the event?

@skyline75489 skyline75489 added Issue-Feature Complex enough to require an in depth planning process and actual budgeted, scheduled work. Area-Performance Performance-related issue labels Jun 29, 2021
@ghost ghost added Needs-Tag-Fix Doesn't match tag requirements Needs-Triage It's a new issue that the core contributor team needs to triage at the next triage meeting labels Jun 29, 2021
@skyline75489
Copy link
Collaborator Author

Just by commenting out the NotifyConsoleUpdateSimpleEvent, you'll get actual 3x performance boost running termbench in OpenConsole (80kcg -> 260kcg).

@lhecker lhecker changed the title Are we gonna do something about NotifyConsoleUpdateSimpleEvent? WriteCharsLegacy performance issues caused by NotifyConsoleUpdateSimpleEvent Jun 29, 2021
@lhecker
Copy link
Member

lhecker commented Jun 29, 2021

Returning early from SCREEN_INFORMATION::NotifyAccessibilityEventing improves my performance only by ~10%.
image

I highly suspect that both you and @DHowett got WT's a11y features enabled, despite not wanting nor needing it. The question is, which tool could cause WT to believe that a11y is wanted in the first place? Any idea @carlos-zamora?

@lhecker
Copy link
Member

lhecker commented Jun 29, 2021

Hmm, running accevent.exe (and thus enabling UIA) doesn't change the performance for me much either... So why does @skyline75489's trace show such a high CPU time in NotifyConsoleUpdateSimpleEvent?

@DHowett
Copy link
Member

DHowett commented Jun 29, 2021

This reminds me a bit of #410 (comment), but it's a simple event and not a sizing event... hm.

@DHowett
Copy link
Member

DHowett commented Jun 29, 2021

To be fair, however: enabling any event causes us to send all events, due to the architecture of the legacy accessibility eventing system.

@DHowett
Copy link
Member

DHowett commented Jun 29, 2021

Interesting. We do not disable accessibility notification in ConPTY. Are we wasting cycles doing this when we're sitting behind Terminal (or Code, or something else) too?

@lhecker
Copy link
Member

lhecker commented Jun 29, 2021

@DHowett I was already wondering why we're posting MSAA events, when WT already has it's own UIA integration.
So basically, if I understand you correctly, we can disable MSAA entirely for ConPTY and in our OpenConsole build (which unlike conhost is only used by WT), right?

@DHowett
Copy link
Member

DHowett commented Jun 29, 2021

I'd rather disable it specifically when we're hosting a PTY -- we don't want to be sending those events when we're doing ConPTY using the Windows inbox infrastructure either :)

@DHowett
Copy link
Member

DHowett commented Jun 29, 2021

Chester may also just be testing openconsole directly. It's a good testbed for the raw performance of one round of VT parsing with no VT string formatting.

@skyline75489
Copy link
Collaborator Author

@DHowett is right. I was testing only OpenConsole. The screenshot shot and the 3x boost come from running OpenConsole directly.

@skyline75489
Copy link
Collaborator Author

This is how it looks like with WT:

image

Basically the same thing as @lhecker posted.

@skyline75489
Copy link
Collaborator Author

So the ConPTY part is obviously fixable and profitable as shown in #10537. Are we do something about the OpenConsole part of this issue? That's a painfully obvious performance bottleneck that I think I first noticed in the year of 2020.

@DHowett
Copy link
Member

DHowett commented Jul 2, 2021

We can only make it faster; we cannot remove it, as there are applications with a dependency on our legacy accessibility events.

@skyline75489
Copy link
Collaborator Author

We can only make it faster; we cannot remove it, as there are applications with a dependency on our legacy accessibility events.

😢

I don't have enough knowledge to make it faster without breaking other applications. Maybe someone can shine some light on this particular subject, when they have the time.

@miniksa
Copy link
Member

miniksa commented Jul 6, 2021

If we think of accessibility like a renderer to a screen reader... then it may be acceptable to coalesce the events coming out of it and skip frames or only report some of the information over the MSAA channel since no one could reasonably be expected to "read" all of that information anyway.

However, node.js and presumably other things globally hook MSAA events in some versions as a way of getting notifications that the buffer data has changed and scraping all of its context out of it... because it took us a really long time to provide something like ConPTY and that was their only option. They DO want to "read" ALL of the information, so skipping frames doesn't work for them.

I think the only way out of this box is through ConPTY and you're not going to fix it for conhost. You could choose to fix it for your own personal OpenConsole where you don't need the MSAA events... or we could add some sort of MSAA-opt-out flag on startup of conhost that turns them off if you know you don't need them... but not by default in the OS. The strategy there is to just migrate away from conhost as the headed environment.

@DHowett
Copy link
Member

DHowett commented Jul 6, 2021

Node we know about -- it uses it solely for resize, which we really should address by having a better resize channel.

It's the nebulous "other things" that we can't know. :)

@miniksa
Copy link
Member

miniksa commented Jul 6, 2021

Node we know about -- it uses it solely for resize, which we really should address by having a better resize channel.

Ah yes. Thank you for reminding me. Unfortunately it has to subscribe to all of them, I believe? Or by subscribing to the one event, it does it for all processes and that's slow? Something something global table in user32k.

It's the nebulous "other things" that we can't know. :)

Yes. I'm thinking that the class of alternative Windows terminal environments pre-ConPTY might be using some or all of this mechanism for eventing.

Further, though. I think it MIGHT be okay to batch up NotifyConsoleUpdateSimpleEvents into a big NotifyConsoleUpdateRegionEvent for massive/bulk text output. But someone would have to go find tools that use it and prove my theory.

ghost pushed a commit that referenced this issue Jul 6, 2021
Don't notify a11y event when in ConPTY mode

In support of #10528
@j4james
Copy link
Collaborator

j4james commented Jul 6, 2021

Is there not perhaps some way we can determine whether any applications have registered for accessibility events, and thus skip sending them if we know that nobody is listening? For example, the docs for NotifyWinEvent say that "Servers may receive a WM_GETOBJECT message immediately after calling this function". So if there was an event we could generate at startup which was guaranteed to receive a WM_GETOBJECT callback, could we then be certain that nobody was listening if we didn't receive one?

@zadjii-msft zadjii-msft added Help Wanted We encourage anyone to jump in on these. Issue-Task It's a feature request, but it doesn't really need a major design. Product-Conhost For issues in the Console codebase and removed Issue-Feature Complex enough to require an in depth planning process and actual budgeted, scheduled work. labels Jul 7, 2021
@ghost ghost removed the Needs-Tag-Fix Doesn't match tag requirements label Jul 7, 2021
@zadjii-msft zadjii-msft added this to the Terminal Backlog milestone Jul 7, 2021
@zadjii-msft zadjii-msft removed the Needs-Triage It's a new issue that the core contributor team needs to triage at the next triage meeting label Jul 7, 2021
DHowett pushed a commit that referenced this issue Jul 7, 2021
Don't notify a11y event when in ConPTY mode

In support of #10528

(cherry picked from commit 59239e3)
DHowett pushed a commit that referenced this issue Jul 7, 2021
Don't notify a11y event when in ConPTY mode

In support of #10528

(cherry picked from commit 59239e3)
@miniksa
Copy link
Member

miniksa commented Jul 9, 2021

Looking behind NotifyWinEvent's code... it checks for an installed event hook locally in the user side within a structure quickly before making the kernel transition. So it should only be a tiny overhead (ETW-like) as long as no one is listening.

My interpretation of that particular line though, James, is that you only get WM_GETOBJECT callbacks for MSAA if the other side is specifically requesting information about a certain UI object positioning. But we don't have distinct UI objects... really. The console events just sort of declare things that listeners generally turn into Console API calls to get more information instead of querying them through the MSAA object framework.

I think it would just take someone playing around with all of these things to figure it out. Find a screen reader that uses our MSAA events... mess around with some changes... etc.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-Performance Performance-related issue Help Wanted We encourage anyone to jump in on these. Issue-Task It's a feature request, but it doesn't really need a major design. Product-Conhost For issues in the Console codebase
Projects
None yet
Development

No branches or pull requests

6 participants