@@ -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