-
Notifications
You must be signed in to change notification settings - Fork 8.3k
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
Set memory order on slow atomics #6920
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -162,17 +162,17 @@ DWORD WINAPI RenderThread::_ThreadProc() | |
{ | ||
WaitForSingleObject(_hPaintEnabledEvent, INFINITE); | ||
|
||
if (!_fNextFrameRequested.exchange(false)) | ||
if (!_fNextFrameRequested.exchange(false, std::memory_order_acq_rel)) | ||
{ | ||
// <-- | ||
// If `NotifyPaint` is called at this point, then it will not | ||
// set the event because `_fWaiting` is not `true` yet so we have | ||
// to check again below. | ||
|
||
_fWaiting.store(true); | ||
_fWaiting.store(true, std::memory_order_release); | ||
|
||
// check again now (see comment above) | ||
if (!_fNextFrameRequested.exchange(false)) | ||
if (!_fNextFrameRequested.exchange(false, std::memory_order_acq_rel)) | ||
{ | ||
// Wait until a next frame is requested. | ||
WaitForSingleObject(_hEvent, INFINITE); | ||
|
@@ -193,7 +193,7 @@ DWORD WINAPI RenderThread::_ThreadProc() | |
// expensive operation, we should reset the event to not render | ||
// again if nothing changed. | ||
|
||
_fWaiting.store(false); | ||
_fWaiting.store(false, std::memory_order_release); | ||
|
||
// see comment above | ||
ResetEvent(_hEvent); | ||
|
@@ -218,13 +218,13 @@ DWORD WINAPI RenderThread::_ThreadProc() | |
|
||
void RenderThread::NotifyPaint() | ||
{ | ||
if (_fWaiting.load()) | ||
if (_fWaiting.load(std::memory_order_acquire)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I mean... Technically you can shave off a bit time here on x86 as well. While x86 doesn't make a distinction between relaxed and release, it does invalidate caches during an acquire (and that way previously "released" data is being sync'd into your "acquiring" thread). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think I'm just going to leave it for now. I'm still not 100% comfortable with all this "manual memory order" business. And you did say above that your relaxed recommendation was provided without liability. :P So if the liability is mine, I'd like to stay in my comfy place for right now and consider relaxed in the future. |
||
{ | ||
SetEvent(_hEvent); | ||
} | ||
else | ||
{ | ||
_fNextFrameRequested.store(true); | ||
_fNextFrameRequested.store(true, std::memory_order_release); | ||
} | ||
} | ||
|
||
|
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.
So if I understand it properly, this one probably shouldn't be relaxed because you're checking two different atomics instead of just one (and hoping for consistency across both), right?
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.
It can be "relaxed" because the "release" would make prior writes from this thread visible to other threads who "acquire"
_fWaiting
's value. But in this case the only one "acquiring" its value isNotifyPaint()
, which doesn't need any prior writes done by_ThreadProc
, since the only thingNotifyPaint()
does is write to_fNextFrameRequested
(but it doesn't rely upon its value, nor does it rely on any other value).(This information is supplied without liability. ⚖😄)