@@ -1467,26 +1467,49 @@ ur_result_t ur_queue_handle_t_::resetCommandList(
1467
1467
std::back_inserter (EventListToCleanup));
1468
1468
EventList.clear ();
1469
1469
} else if (!isDiscardEvents ()) {
1470
- // For immediate commandlist reset only those events that have signalled.
1471
1470
// 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 );
1474
1474
ze_result_t ZeResult =
1475
- (*it) ->Completed
1475
+ Event ->Completed
1476
1476
? 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 ();) {
1478
1504
// Break early as soon as we found first incomplete event because next
1479
1505
// events are submitted even later. We are not trying to find all
1480
1506
// completed events here because it may be costly. I.e. we are checking
1481
1507
// only elements which are most likely completed because they were
1482
1508
// submitted earlier. It is guaranteed that all events will be eventually
1483
1509
// cleaned up at queue sync/release.
1484
- if (ZeResult == ZE_RESULT_NOT_READY )
1510
+ if (! EventCompleted (*it) )
1485
1511
break ;
1486
1512
1487
- if (ZeResult != ZE_RESULT_SUCCESS)
1488
- return ze2urResult (ZeResult);
1489
-
1490
1513
EventListToCleanup.push_back (std::move ((*it)));
1491
1514
it = EventList.erase (it);
1492
1515
}
0 commit comments