-
Notifications
You must be signed in to change notification settings - Fork 83
Global cache lock hurts cache hits during heavily concurrent builds #160
Description
Hi!
I tried to use clcache for my project and found speed up only on 35% (23 min vs 35 min). This result greatly embarrassed me because ccache at Linux and MacOS boost build time more then 10 times. I try change msbuild to ninja, but it gave similar results.
Then I suggested problem in long waits at lock (at other machine I even got crashes by timeouts). I try cut all lock logic and stats file overwriting. See diff below. Then build time became less then 7 min! It's more then 3 times faster. Looks like absolutely unacceptable overhead for writing statistics.
I'm not sure is access to manifests needs lock too, but looks if it is, we can do it more optimal. And about statistics, I think we can write simple server for writing it with locks, and clcache processes will just sent stat to server and exit without waiting responce. Or we can add option to disable statistics (and lock respectively) as quick fix.
--- a/clcache.py
+++ b/clcache.py
@@ -123,6 +123,7 @@ class ObjectCacheLock(object):
WAIT_ABANDONED_CODE = 0x00000080
def __init__(self, mutexName, timeoutMs):
+ return
mutexName = 'Local\\' + mutexName
self._mutex = windll.kernel32.CreateMutexW(
wintypes.INT(0),
@@ -133,17 +134,21 @@ class ObjectCacheLock(object):
assert self._mutex
def __enter__(self):
+ return
if not self._acquired:
self.acquire()
def __exit__(self, typ, value, traceback):
+ return
if self._acquired:
self.release()
def __del__(self):
+ return
windll.kernel32.CloseHandle(self._mutex)
def acquire(self):
+ return
result = windll.kernel32.WaitForSingleObject(
self._mutex, wintypes.INT(self._timeoutMs))
if result not in [0, self.WAIT_ABANDONED_CODE]:
@@ -154,6 +159,7 @@ class ObjectCacheLock(object):
self._acquired = True
def release(self):
+ return
windll.kernel32.ReleaseMutex(self._mutex)
self._acquired = False
@@ -373,8 +394,9 @@ class PersistentJSONDict(object):
def save(self):
if self._dirty:
- with open(self._fileName, 'w') as f:
- json.dump(self._dict, f, sort_keys=True, indent=4)
+ pass
+ #with open(self._fileName, 'w') as f:
+ # json.dump(self._dict, f, sort_keys=True, indent=4)
def __setitem__(self, key, value):
self._dict[key] = value