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

Use Convert.To after rounding in Pack() to avoid different behavior on ARM vs x86/x64 #1790

Merged
merged 4 commits into from
Oct 27, 2021

Conversation

brianpopow
Copy link
Collaborator

Prerequisites

  • I have written a descriptive pull-request title
  • I have verified that there are no overlapping pull-requests open
  • I have verified that I am following the existing coding patterns and practice as demonstrated in the repository. These follow strict Stylecop rules 👮.
  • I have provided test coverage for my change (where applicable)

Description

I noticed some pixelformat tests failing on ARM64. Namly short2, short4, normalizedbyte4 tests.
The reason for that is a cast from float to int in Pack. on ARM this gets rounded to 0, if its negative, while on x86/x64 its not.

For example:

float f = -100.0f;
uint fuint = (uint)f;

Result on ARM64: 0
Result on x64: 4294967196 (uint.Max + f + 1)

To avoid the difference, i have added a Convert.ToInt32 after the rounding.
The rest of the changes are some minor cleanup.

@codecov
Copy link

codecov bot commented Oct 24, 2021

Codecov Report

Merging #1790 (a68aea3) into master (2add3e1) will decrease coverage by 0.07%.
The diff coverage is 100.00%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #1790      +/-   ##
==========================================
- Coverage   87.10%   87.03%   -0.08%     
==========================================
  Files         936      936              
  Lines       47649    47631      -18     
  Branches     6015     6015              
==========================================
- Hits        41506    41456      -50     
- Misses       5150     5181      +31     
- Partials      993      994       +1     
Flag Coverage Δ
unittests 87.03% <100.00%> (-0.08%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
...ageSharp/PixelFormats/PixelImplementations/La32.cs 92.20% <ø> (ø)
...ImageSharp/PixelFormats/PixelImplementations/A8.cs 90.00% <100.00%> (ø)
...eSharp/PixelFormats/PixelImplementations/Argb32.cs 89.62% <100.00%> (ø)
...geSharp/PixelFormats/PixelImplementations/Bgr24.cs 95.45% <100.00%> (ø)
...eSharp/PixelFormats/PixelImplementations/Bgr565.cs 84.61% <100.00%> (-0.39%) ⬇️
...eSharp/PixelFormats/PixelImplementations/Bgra32.cs 94.79% <100.00%> (ø)
...harp/PixelFormats/PixelImplementations/Bgra4444.cs 84.21% <100.00%> (-0.41%) ⬇️
...harp/PixelFormats/PixelImplementations/Bgra5551.cs 84.61% <100.00%> (-0.39%) ⬇️
...geSharp/PixelFormats/PixelImplementations/Byte4.cs 85.00% <100.00%> (-0.37%) ⬇️
...rp/PixelFormats/PixelImplementations/HalfSingle.cs 84.84% <100.00%> (-0.45%) ⬇️
... and 22 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 2add3e1...a68aea3. Read the comment docs.

@@ -523,7 +520,7 @@ private static string ToRgbaHex(string hex)
return hex + "FF";
}

if (hex.Length < 3 || hex.Length > 4)
if (hex.Length is < 3 or > 4)
Copy link
Contributor

Choose a reason for hiding this comment

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

At the expense of less readable code one can save a comparison here:

Suggested change
if (hex.Length is < 3 or > 4)
if ((uint)(hex.Length - 3) > (4 - 3))

BTW: is this method hot enough worth optimizing? One could save same allocations here.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

@gfoidl thanks for your feedback, but this is not a critical path. I rather keep this readable.

Copy link
Member

Choose a reason for hiding this comment

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

Neat trick... Not hot. It's just used for parsing hex values which are generally defined outside loops.

@JimBobSquarePants
Copy link
Member

I wonder if we should replicate the behavior of the Convert method and produce inlineable version.

https://source.dot.net/#System.Private.CoreLib/Convert.cs,10cd63a0dc4a7c4c

@brianpopow
Copy link
Collaborator Author

I wonder if we should replicate the behavior of the Convert method and produce inlineable version.

https://source.dot.net/#System.Private.CoreLib/Convert.cs,10cd63a0dc4a7c4c

I dont know if its really worth for such niche pixel formats, like short2 and short4.

Copy link
Member

@antonfirsov antonfirsov left a comment

Choose a reason for hiding this comment

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

Looks good. One question.

public readonly Vector4 ToVector4() => new Vector4(0, 0, 0, this.PackedValue / 255F);
public readonly Vector4 ToVector4() => new(0, 0, 0, this.PackedValue / 255F);
Copy link
Member

Choose a reason for hiding this comment

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

So type interference is something we prefer in the codebase?

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 like the shorter new(...) syntax very much. From your question im sensing you are not totally convinced?

Copy link
Member

Choose a reason for hiding this comment

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

I don't have a strong preference, given up on code style battles long time ago 😄

Just want see us making a conscious decision on this, and have a preferred style established. @JimBobSquarePants your thoughts?

Copy link
Member

Choose a reason for hiding this comment

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

I'm all in. I absolutely LOVE being able to declare on the left. 😍 Foo foo = new(bar); 😍

@antonfirsov
Copy link
Member

I wonder if we should replicate the behavior of the Convert method and produce inlineable version.

If we really want to spend time optimizing these methods, I'd rather explore how to SIMD them on x86.

Copy link
Member

@JimBobSquarePants JimBobSquarePants left a comment

Choose a reason for hiding this comment

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

Nice job! I think we can leave the Convert as-is and focus on potential bulk optimization for V3.

@JimBobSquarePants JimBobSquarePants merged commit 72904e1 into master Oct 27, 2021
@JimBobSquarePants JimBobSquarePants deleted the bp/pixelformattests branch October 27, 2021 03:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants