Alexei Alexandrov wrote:
I've also noticed that Vim spends somewhat significant time on startup loading 
spell files (I have 2 languages in my .vimrc: set spelllang=en,ru). The time is 
mostly spent in EnterCriticalSection/LeaveCriticalSection with getc() upper the 
stack. The reason for this is CRT blocking since the runtime is multithreaded. 
It's Windows, but on Linux it should be similar.

As far as I understand, Vim doesn't access the spell file from multiple 
threads. Thus, the situation can be improved a lot: on Linux by using 
getc_unlocked. On Windows, starting VS 2005 there is a function _getc_nolock. 
Before VS 2005 this function can be emulated by macro:

#define _getc_nolock(_stream) (--(_stream)->_cnt >= 0 ? \
                              0xff & *(_stream)->_ptr++ : _filbuf(_stream))

By switching to non-blocking getc() in spell.c I was able to reduce Vim startup 
time from about 0.9 seconds to about 0.7 seconds.

How did you measure the time in EnterCriticalSection and LeaveCriticalSection? If there's no lock contention, these routines are little more than InterlockedIncrement and InterlockedDecrement, without a kernel transition or blocking. If the lock is already held, then by definition, EnterCriticalSection has to block until the lock is available. Similarly, if LeaveCriticalSection detects that there are other callers waiting, it will signal one of the waiters.

In other words, if you're seeing significant time in Enter/LeaveCS, I can think of two causes. Either your measurement tool has perturbed the results, or there really is some multithreaded lock contention. The former seems more likely, as Vim is single-threaded, but who knows what some DLLs in the Vim process might be doing.

I would be vary wary of using the _getc_nolock macro until we understand why you are seeing those results.

--
/George V. Reilly  [EMAIL PROTECTED]
http://www.georgevreilly.com/blog
The biggest mistake is not learning from all your other mistakes.

Reply via email to