changes to duchain lock: can anybody reproduce this speedup?

Sven Brauch mail at svenbrauch.de
Sat Jul 16 01:47:00 UTC 2016


Hey,

I wanted to look at the locking strategy of the DUChain lock for a
while, but never got around to do it. Now, at 3:30 am on a friday, I
finally did (what else would you do at this time) and the results are at
least ... interesting:

Replacing QThread::usleep(500) with sched_yield() makes the number of
effective used CPUs go up from ~1.7 to ~3.3 and the wall clock time down
from ~170 to ~110 seconds on duchainify kdevplatform [1]. See:
https://paste.kde.org/pncqjowxp
For kdev-python, the effect is somewhat less severe but still  noticeable:
https://paste.kde.org/pcirhvys9

Could anyone try the attached (5-line) patch and look if you see this
speedup as well? I feel like I might be doing something wrong.

On the other hand, I think the "sleep 500us" strategy is quite terrible,
if only because 500us is relatively a long time and nothing else will
happen during that wait for _any_ thread iirc.

Good night,
Sven

________________
[1] Conditions: everything built in release mode, CLEAR_DUCHAIN_DIR=1
set before invocation, -r -u flags passed to duchainify, 4 threads, CPU
is a 4-core (8 threads with hyperthreading) Intel i7 3720 QM
-------------- next part --------------
diff --git a/language/duchain/duchainlock.cpp b/language/duchain/duchainlock.cpp                                                                                                             
index aa842ce..12f2ef6 100644                                                                                                                                                                
--- a/language/duchain/duchainlock.cpp                                                                                                                                                       
+++ b/language/duchain/duchainlock.cpp                                                                                                                                                       
@@ -26,6 +26,9 @@                                                                                                                                                                            
 #include <QThreadStorage>                                                                                                                                                                   
 #include <QElapsedTimer>                                                                                                                                                                    
                                                                                                                                                                                             
+#ifdef Q_OS_LINUX                                                                                                                                                                           
+#include <sched.h>                                                                                                                                                                          
+#endif                                                                                                                                                                                      
                                                                                                                                                                                             
 ///@todo Always prefer exactly that lock that is requested by the thread that has the foreground mutex,                                                                                     
 ///           to reduce the amount of UI blocking.                                                                                                                                          
@@ -94,7 +97,7 @@ bool DUChainLock::lockForRead(unsigned int timeout)                                                                                                                        
                                                                                                                                                                                             
     while (d->m_writer.loadAcquire()) {                                                                                                                                                     
       if (!timeout || t.elapsed() < timeout) {                                                                                                                                              
-        QThread::usleep(uSleepTime);                                                                                                                                                        
+        sched_yield();                                                                                                                                                                      
       } else {                                                                                                                                                                              
         //Fail!                                                                                                                                                                             
         d->changeOwnReaderRecursion(-1);                                                                                                                                                    
@@ -149,7 +152,7 @@ bool DUChainLock::lockForWrite(uint timeout)                                                                                                                             
     }                                                                                                                                                                                       
                                                                                                                                                                                             
     if (!timeout || t.elapsed() < timeout) {                                                                                                                                                
-      QThread::usleep(uSleepTime);                                                                                                                                                          
+      sched_yield();                                                                                                                                                                        
     } else {                                                                                                                                                                                
       //Fail!                                                                                                                                                                               
       return false;   
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: OpenPGP digital signature
URL: <http://mail.kde.org/pipermail/kdevelop-devel/attachments/20160716/5fa887db/attachment.sig>


More information about the KDevelop-devel mailing list