-
Notifications
You must be signed in to change notification settings - Fork 796
[SYCL] Do not lock unconditionally while access queue_iml::MInOrderExternalEvent #17575
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
Changes from 1 commit
5dfc457
2af3dec
32a8487
4bd575c
2b1b35f
1cdfa2b
ed1c0c4
647a8fb
5b3a159
9332d0e
ec7cce0
3b24720
e3afeba
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 |
|---|---|---|
|
|
@@ -711,13 +711,18 @@ class queue_impl { | |
|
|
||
| void setExternalEvent(const event &Event) { | ||
| std::lock_guard<std::mutex> Lock(MInOrderExternalEventMtx); | ||
| MHasValueInOrderExternalEvent.store(true, std::memory_order_release); | ||
| MInOrderExternalEvent = Event; | ||
| } | ||
|
|
||
| std::optional<event> popExternalEvent() { | ||
| std::lock_guard<std::mutex> Lock(MInOrderExternalEventMtx); | ||
| std::optional<event> Result = std::nullopt; | ||
| std::swap(Result, MInOrderExternalEvent); | ||
|
|
||
| if (MHasValueInOrderExternalEvent.load(std::memory_order_acquire)) { | ||
| std::lock_guard<std::mutex> Lock(MInOrderExternalEventMtx); | ||
| MHasValueInOrderExternalEvent.store(false, std::memory_order_release); | ||
| std::swap(Result, MInOrderExternalEvent); | ||
| } | ||
| return Result; | ||
| } | ||
|
|
||
|
|
@@ -833,8 +838,10 @@ class queue_impl { | |
| // dependency so in the case where some commands were not enqueued | ||
| // (blocked), we track them to prevent barrier from being enqueued | ||
| // earlier. | ||
| if (MAreCleanupRequestsMissed.load(std::memory_order_acquire)) | ||
| { | ||
| std::lock_guard<std::mutex> RequestLock(MMissedCleanupRequestsMtx); | ||
| MAreCleanupRequestsMissed.store(false, std::memory_order_release); | ||
| for (auto &UpdatedGraph : MMissedCleanupRequests) | ||
| doUnenqueuedCommandCleanup(UpdatedGraph); | ||
| MMissedCleanupRequests.clear(); | ||
|
|
@@ -850,12 +857,12 @@ class queue_impl { | |
| auto EventRet = Handler.finalize(); | ||
| EventImplPtr EventRetImpl = getSyclObjImpl(EventRet); | ||
| if (Type == CGType::CodeplayHostTask) | ||
| Deps.UnenqueuedCmdEvents.push_back(EventRetImpl); | ||
| Deps.UnenqueuedCmdEvents.push_back(std::move(EventRetImpl)); | ||
|
||
| else if (Type == CGType::Barrier || Type == CGType::BarrierWaitlist) { | ||
| Deps.LastBarrier = EventRetImpl; | ||
| Deps.LastBarrier = std::move(EventRetImpl); | ||
| Deps.UnenqueuedCmdEvents.clear(); | ||
| } else if (!EventRetImpl->isEnqueued()) { | ||
| Deps.UnenqueuedCmdEvents.push_back(EventRetImpl); | ||
| Deps.UnenqueuedCmdEvents.push_back(std::move(EventRetImpl)); | ||
| } | ||
|
|
||
| return EventRet; | ||
|
|
@@ -1040,6 +1047,8 @@ class queue_impl { | |
| // the fallback implementation of profiling info | ||
| bool MFallbackProfiling = false; | ||
|
|
||
| // Is value presented in MInOrderExternalEvent? | ||
| std::atomic_bool MHasValueInOrderExternalEvent = false; | ||
|
||
| // This event can be optionally provided by users for in-order queues to add | ||
| // an additional dependency for the subsequent submission in to the queue. | ||
| // Access to the event should be guarded with MInOrderExternalEventMtx. | ||
|
|
@@ -1071,6 +1080,7 @@ class queue_impl { | |
| std::deque<std::shared_ptr<ext::oneapi::experimental::detail::graph_impl>> | ||
| MMissedCleanupRequests; | ||
| std::mutex MMissedCleanupRequestsMtx; | ||
| std::atomic_bool MAreCleanupRequestsMissed = false; | ||
|
|
||
| friend class sycl::ext::oneapi::experimental::detail::node_impl; | ||
|
|
||
|
|
||
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.
Why is the following not an issue:
?
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.
Thank you, this is exactly the question I would like to discuss with the fellow sycl experts!
According to my understanding, the change is correct, because the situation you describing is undistinguishing from a situation when Thread A just staying, say, at the beginning of
queue_impl::revisitUnenqueuedCommandsState(), i.e. there is no reason for Thread B to expect something inMMissedCleanupRequestsat this point.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.
@sergey-semenov , @KseniyaTikhomirova would be much more knowledgeable about this than I am.
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.
Chatted with @KseniyaTikhomirova about this today. Like Alexandr said, the case is indistinguishable from the first thread being earlier in its execution path.
With the synchronization being made less strict, it will be slightly more likely that we'll exit
queue::waitwith some dependency related data still present in the queue. But that's not a functional problem since that data will be handled during the next cleanup call.