Skip to content

Commit a02b1a5

Browse files
author
Jaime Arteaga
committed
Port Heuristically reduce overhead from immediate command-list cleanup
intel#9052 Signed-off-by: Jaime Arteaga <[email protected]>
1 parent d39759a commit a02b1a5

File tree

2 files changed

+33
-10
lines changed

2 files changed

+33
-10
lines changed

sycl/plugins/unified_runtime/ur/adapters/level_zero/ur_level_zero_context.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -518,7 +518,7 @@ ur_context_handle_t_::decrementUnreleasedEventsInPool(ur_event_handle_t Event) {
518518
static const size_t ImmCmdListsEventCleanupThreshold = [] {
519519
const char *ImmCmdListsEventCleanupThresholdStr = std::getenv(
520520
"SYCL_PI_LEVEL_ZERO_IMMEDIATE_COMMANDLISTS_EVENT_CLEANUP_THRESHOLD");
521-
static constexpr int Default = 20;
521+
static constexpr int Default = 1000;
522522
if (!ImmCmdListsEventCleanupThresholdStr)
523523
return Default;
524524

sycl/plugins/unified_runtime/ur/adapters/level_zero/ur_level_zero_queue.cpp

Lines changed: 32 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1467,26 +1467,49 @@ ur_result_t ur_queue_handle_t_::resetCommandList(
14671467
std::back_inserter(EventListToCleanup));
14681468
EventList.clear();
14691469
} else if (!isDiscardEvents()) {
1470-
// For immediate commandlist reset only those events that have signalled.
14711470
// If events in the queue are discarded then we can't check their status.
1472-
for (auto it = EventList.begin(); it != EventList.end();) {
1473-
std::scoped_lock<ur_shared_mutex> EventLock((*it)->Mutex);
1471+
// Helper for checking of event completion
1472+
auto EventCompleted = [](ur_event_handle_t Event) -> bool {
1473+
std::scoped_lock<ur_shared_mutex> EventLock(Event->Mutex);
14741474
ze_result_t ZeResult =
1475-
(*it)->Completed
1475+
Event->Completed
14761476
? ZE_RESULT_SUCCESS
1477-
: ZE_CALL_NOCHECK(zeEventQueryStatus, ((*it)->ZeEvent));
1477+
: ZE_CALL_NOCHECK(zeEventQueryStatus, (Event->ZeEvent));
1478+
return ZeResult == ZE_RESULT_SUCCESS;
1479+
};
1480+
// Handle in-order specially as we can just in few checks (with binary
1481+
// search) a completed event and then all events before it are also
1482+
// done.
1483+
if (isInOrderQueue()) {
1484+
size_t Bisect = EventList.size();
1485+
size_t Iter = 0;
1486+
for (auto it = EventList.rbegin(); it != EventList.rend(); ++Iter) {
1487+
if (!EventCompleted(*it)) {
1488+
if (Bisect > 1 && Iter < 3) { // Heuristically limit by 3 checks
1489+
Bisect >>= 1;
1490+
it += Bisect;
1491+
continue;
1492+
}
1493+
break;
1494+
}
1495+
// Bulk move of event up to "it" to the list ready for cleanup
1496+
std::move(it, EventList.rend(), std::back_inserter(EventListToCleanup));
1497+
EventList.erase(EventList.begin(), it.base());
1498+
break;
1499+
}
1500+
return UR_RESULT_SUCCESS;
1501+
}
1502+
// For immediate commandlist reset only those events that have signalled.
1503+
for (auto it = EventList.begin(); it != EventList.end();) {
14781504
// Break early as soon as we found first incomplete event because next
14791505
// events are submitted even later. We are not trying to find all
14801506
// completed events here because it may be costly. I.e. we are checking
14811507
// only elements which are most likely completed because they were
14821508
// submitted earlier. It is guaranteed that all events will be eventually
14831509
// cleaned up at queue sync/release.
1484-
if (ZeResult == ZE_RESULT_NOT_READY)
1510+
if (!EventCompleted(*it))
14851511
break;
14861512

1487-
if (ZeResult != ZE_RESULT_SUCCESS)
1488-
return ze2urResult(ZeResult);
1489-
14901513
EventListToCleanup.push_back(std::move((*it)));
14911514
it = EventList.erase(it);
14921515
}

0 commit comments

Comments
 (0)