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.