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

Add fast lookup path for DxFontInfo #10521

Merged
6 commits merged into from Jul 9, 2021

Conversation

skyline75489
Copy link
Collaborator

@skyline75489 skyline75489 commented Jun 27, 2021

Fixes the performance regression caused by DxFontInfo.

DxFontInfo introduced in #9201

@skyline75489
Copy link
Collaborator Author

This feels very draft to me. I don't like most of it, but it certainly works.

Before:

image

After:

image

@skyline75489 skyline75489 changed the title Added fast lookup path for DxFontInfo Add fast lookup path for DxFontInfo Jun 27, 2021
Copy link
Member

@DHowett DHowett left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Curious questions

@ghost ghost added Needs-Author-Feedback The original author of the issue/PR needs to come back and respond to something and removed Needs-Author-Feedback The original author of the issue/PR needs to come back and respond to something labels Jun 28, 2021
@lhecker
Copy link
Member

lhecker commented Jul 2, 2021

Correct me if I'm wrong, but as far as I can see the existing code that is being improved here isn't optimal in the first place. We don't have to make the hashing faster if we remove the need for expensive hashing.

Reasons:

  • The only place where _textFormatMap is being used is inside DxFontRenderData::TextFormatWithAttribute
  • _textFormatMap is cleared when the font changes and can only contain a single font ❗
  • _textFormatMap lookup only occurs with weight, style and stretch (let's abbreviate it as "WSS")

My personal conclusion:
The hash function for _textFormatMap only needs to hash WSS and that's it. We can improve the performance of hashing by inlining the FNV1a algorithm, which requires around 4ns for 12 bytes (the amount of data we need to hash) in my experience. If we use xxHash we can reduce it to 1-2ns.

Edit: In fact we can cram all 3 values into a single uint32_t lol.

@lhecker
Copy link
Member

lhecker commented Jul 2, 2021

I just saw this is already being discussed by you two...
Well in this case I'd be in favor of creating a custom hash that doesn't specialize std::hash. That way accidental misuse can be prevented and performance guaranteed. 👍

@skyline75489
Copy link
Collaborator Author

skyline75489 commented Jul 2, 2021

That way accidental misuse can be prevented and performance guaranteed.

I like the idea of custom high-performance cache, too. Will try to implement it later.

Note from Leonard:

you don't have to write a new class IMO
it should be enough to just create a custom struct HighPerformanceFontInfoHasher or something 😄

src/renderer/dx/DxFontRenderData.cpp Outdated Show resolved Hide resolved
@ghost ghost added the Needs-Author-Feedback The original author of the issue/PR needs to come back and respond to something label Jul 6, 2021
@skyline75489 skyline75489 force-pushed the chesterliu/dev/dxfontinfo-perf branch from b44354f to af2a230 Compare July 7, 2021 00:36
@ghost ghost removed the Needs-Author-Feedback The original author of the issue/PR needs to come back and respond to something label Jul 7, 2021
Copy link
Member

@DHowett DHowett left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did we end up removing the "check if it is the default font" case? Did it not provide a performance benefit?

src/renderer/dx/DxFontRenderData.cpp Show resolved Hide resolved
src/renderer/dx/DxFontRenderData.cpp Show resolved Hide resolved
@DHowett
Copy link
Member

DHowett commented Jul 9, 2021

@msftbot make sure @lhecker signs off

@ghost ghost added the AutoMerge Marked for automatic merge by the bot when requirements are met label Jul 9, 2021
@ghost
Copy link

ghost commented Jul 9, 2021

Hello @DHowett!

Because you've given me some instructions on how to help merge this pull request, I'll be modifying my merge approach. Here's how I understand your requirements for merging this pull request:

  • I'll only merge this pull request if it's approved by @lhecker

If this doesn't seem right to you, you can tell me to cancel these instructions and use the auto-merge policy that has been configured for this repository. Try telling me "forget everything I just told you".

@DHowett
Copy link
Member

DHowett commented Jul 9, 2021

@lhecker if you agree with the suggestions, you can use the UI to commit them to Chester's branch 😄

@DHowett DHowett removed the AutoMerge Marked for automatic merge by the bot when requirements are met label Jul 9, 2021
Comment on lines +89 to +90
std::unordered_map<FontAttributeMapKey, ::Microsoft::WRL::ComPtr<IDWriteTextFormat>> _textFormatMap;
std::unordered_map<FontAttributeMapKey, ::Microsoft::WRL::ComPtr<IDWriteFontFace1>> _fontFaceMap;
Copy link
Member

@lhecker lhecker Jul 9, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe we can get rid of these hashmaps entirely:
As far as I can see we currently don't actually support dynamic font stretches and don't plan to add them in the foreseeable future. So we can drop those for now, allowing us to simplify our code.

With "stretch" dropped, we currently only support two kinds of bold (on/off) and two kinds of italic (on/off). It's unlikely that this will change in the foreseeable future either.
As I personally generally don't think it's a good idea to plan for the unknown (in programming), I'd like to suggest to change these line to this in a different PR:

::Microsoft::WRL::ComPtr<IDWriteTextFormat>> _textFormatMap[2][2];
::Microsoft::WRL::ComPtr<IDWriteFontFace1>> _fontFaceMap[2][2];

If we then have for instance TextFormatWithAttribute(bool bold, bool italic) we can write _textFormatMap[bold][italic] for 0-overhead access to the format map. No allocations, or complex hashing involved. 👍

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed! This would be an excellent simplification.

I knew we initially designed it for font stretch, but here's what I think now: we can change it if we ever need to easily support Stretch. After all, let's go with the simplest implementation that works for any given problem unless we truly do need a complex one. 😄

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was trying to reply using email. But that email was not sent successfully.

Just want to say I am also OK with the simple implementation. It’s a good idea👍

Co-authored-by: Dustin L. Howett <dustin@howett.net>
@DHowett DHowett added the AutoMerge Marked for automatic merge by the bot when requirements are met label Jul 9, 2021
@ghost
Copy link

ghost commented Jul 9, 2021

Hello @DHowett!

Because this pull request has the AutoMerge label, I will be glad to assist with helping to merge this pull request once all check-in policies pass.

p.s. you can customize the way I help with merging this pull request, such as holding this pull request until a specific person approves. Simply @mention me (@msftbot) and give me an instruction to get started! Learn more here.

@ghost ghost merged commit f339705 into microsoft:main Jul 9, 2021
@skyline75489 skyline75489 deleted the chesterliu/dev/dxfontinfo-perf branch July 12, 2021 23:17
@ghost
Copy link

ghost commented Jul 14, 2021

🎉Windows Terminal Preview v1.10.1933.0 has been released which incorporates this pull request.:tada:

Handy links:

This pull request was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
AutoMerge Marked for automatic merge by the bot when requirements are met
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants