Skip to content

Commit e15c474

Browse files
authored
[SYCL] Avoid lock and wait in KernelProgramCache::getOrBuild (#20780)
Optimized common path when kernel is already build and exists in the cache. Use BuildStatus already provided by _compare_exchange_strong_ instead of taking lock, calling wait and reading it again.
1 parent 52572ab commit e15c474

File tree

1 file changed

+12
-15
lines changed

1 file changed

+12
-15
lines changed

sycl/source/detail/kernel_program_cache.hpp

Lines changed: 12 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -90,15 +90,10 @@ class KernelProgramCache {
9090
/// A mutex to be employed along with MBuildCV.
9191
std::mutex MBuildResultMutex;
9292

93-
BuildState
94-
waitUntilTransition(BuildState From = BuildState::BS_InProgress) {
95-
BuildState To;
93+
BuildState waitUntilTransition() {
9694
std::unique_lock<std::mutex> Lock(MBuildResultMutex);
97-
MBuildCV.wait(Lock, [&] {
98-
To = State;
99-
return State != From;
100-
});
101-
return To;
95+
MBuildCV.wait(Lock, [&] { return State != BuildState::BS_InProgress; });
96+
return State.load();
10297
}
10398

10499
void updateAndNotify(BuildState DesiredState) {
@@ -729,29 +724,31 @@ class KernelProgramCache {
729724
auto /* std::shared_ptr<BuildResult> */
730725
getOrBuild(GetCachedBuildFT &&GetCachedBuild, BuildFT &&Build,
731726
EvictFT &&EvictFunc = nullptr) {
732-
using BuildState = KernelProgramCache::BuildState;
733727
constexpr size_t MaxAttempts = 2;
734728
for (size_t AttemptCounter = 0;; ++AttemptCounter) {
735729
auto /* std::pair<std::shared_ptr<BuildResult>, bool> */ Res =
736730
GetCachedBuild();
737731
auto &BuildResult = Res.first;
738732
assert(BuildResult != nullptr);
739-
BuildState Expected = BuildState::BS_Initial;
740-
BuildState Desired = BuildState::BS_InProgress;
741-
if (!BuildResult->State.compare_exchange_strong(Expected, Desired)) {
733+
BuildState CurrentState = BuildState::BS_Initial; // initial is expected
734+
if (!BuildResult->State.compare_exchange_strong(
735+
CurrentState, BuildState::BS_InProgress)) {
742736
// no insertion took place, thus some other thread has already inserted
743737
// smth in the cache
744-
BuildState NewState = BuildResult->waitUntilTransition();
738+
739+
if (CurrentState == BuildState::BS_InProgress) {
740+
CurrentState = BuildResult->waitUntilTransition();
741+
}
745742

746743
// Build succeeded.
747-
if (NewState == BuildState::BS_Done) {
744+
if (CurrentState == BuildState::BS_Done) {
748745
if constexpr (!std::is_same_v<EvictFT, void *>)
749746
EvictFunc(BuildResult->Val, /*IsBuilt=*/false);
750747
return BuildResult;
751748
}
752749

753750
// Build failed, or this is the last attempt.
754-
if (NewState == BuildState::BS_Failed ||
751+
if (CurrentState == BuildState::BS_Failed ||
755752
AttemptCounter + 1 == MaxAttempts) {
756753
if (BuildResult->Error.isFilledIn())
757754
throw detail::set_ur_error(

0 commit comments

Comments
 (0)