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

[Performance] Convert ASLayoutElementSize to atomic #trivial #331

Merged

Conversation

hannahmbanana
Copy link
Contributor

Resolves #318

@CLAassistant
Copy link

CLAassistant commented Jun 6, 2017

CLA assistant check
All committers have signed the CLA.

@hannahmbanana hannahmbanana changed the title [Performance] Convert ASLayoutElementSize to atomic [Performance] Convert ASLayoutElementSize to atomic #trivial Jun 6, 2017
Copy link
Member

@Adlai-Holler Adlai-Holler left a comment

Choose a reason for hiding this comment

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

Unfortunately this isn't correct.

I don't know that there is any way to achieve this with an atomic.

Now, we could definitely have the storage here be atomic<CGFloat> width, atomic<CGFloat> height etc, and only use a lock when reading/writing .size, and build the size out of those different fields, but I think that would be pretty ugly and probably wouldn't provide a justifying performance improvement.

@appleguy Thoughts?

_size.height = height;
ASLayoutElementSize newSize = _size.load();
newSize.height = height;
_size.store(newSize);
Copy link
Member

Choose a reason for hiding this comment

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

Unfortunately this breaks atomicity =/ Imagine:

Thread 1: read size A
Thread 2: read size A
Thread 1: write size { A, height = x }
Thread 2: write size { A, width = y }

So we end up with size { A, width = y }, thread 2 overwrote thread 1's change. We should have ended up with size { A, height = x, width = y }.

We have to do the read-update-write all in one operation.

ASLayoutElementSize newSize = _size.load();
newSize.maxWidth = maxLayoutSize.width;
newSize.maxHeight = maxLayoutSize.height;
_size.store(newSize);
Copy link
Member

Choose a reason for hiding this comment

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

What if _size is changed after it's loaded here but before the new size is stored?

@appleguy
Copy link
Member

appleguy commented Jun 6, 2017

@Adlai-Holler @nguyenhuy good catch. I hadn't considered the size writing problem with this.

Is it correct that the issue only occurs in the writing methods, and that it would occur for all the writing methods including the ones for scalar values in the struct?

I think this would still be worth the win if we take the lock for the writing cases and let reading use the atomic directly. Reads are drastically more common than writes, especially because of relayouts that often get performed on the main thread.

@nguyenhuy
Copy link
Member

@appleguy Sadly I don't think acquiring the lock only in writing methods will work. @Adlai-Holler Please correct me if I'm wrong.

@hannahmbanana
Copy link
Contributor Author

hannahmbanana commented Jun 10, 2017

@nguyenhuy @Adlai-Holler If the atomic were kept and then also the lock used in the writing methods, why would this not work?

This is ready for another review. Let me know if you can think of another accessing way that would break this.

@appleguy
Copy link
Member

@Adlai-Holler @nguyenhuy I've taken a look, and could be missing something, but this seems safe to me...very curious to know what I might have failed to consider.

Copy link
Member

@Adlai-Holler Adlai-Holler left a comment

Choose a reason for hiding this comment

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

Hmmm 2% of CPU is no joke, but this pattern also isn't very scalable. Since this is such an insanely hot variable, let's roll with this ⚡️

Copy link
Member

@nguyenhuy nguyenhuy left a comment

Choose a reason for hiding this comment

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

Talked to Adlai about it, let's get this in.

@hannahmbanana
Copy link
Contributor Author

@appleguy - I don't have merge permissions, could you land this?

@nguyenhuy nguyenhuy merged commit 8861161 into TextureGroup:master Jun 13, 2017
@nguyenhuy
Copy link
Member

Don't worry, I got it :)

bernieperez pushed a commit to AtomTickets/Texture that referenced this pull request Apr 25, 2018
…Group#331)

* [Performance] Convert ASLayoutElementSize to atomic

* [ASLayoutElementStyle] Put locks around setter methods.

* Also add lock to setSize: internal method.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants