[prev in list] [next in list] [prev in thread] [next in thread] 

List:       cygwin
Subject:    Re: Cygwin speed
From:       Christian Franke <Christian.Franke () t-online ! de>
Date:       2007-03-07 20:13:33
Message-ID: 45EF1CED.608 () t-online ! de
[Download RAW message or body]

Christopher Layne wrote:
> On Fri, Mar 02, 2007 at 11:11:54AM -0800, Brian Dessent wrote:
>> Vinod Gupta wrote:
>>
>>> Cygwin was a slow by a factor of 3x. Is that normal?
>> Yes.  Emulation of POSIX functions which do not exist on Windows is
>> expensive.  Fork is especially bad, which is all you're really testing
>> there.
>
> Where is the *continual* fork in his script btw?

There is no fork at all, the script uses only builtin shell commands.

This command prints the fork() count of a script on Cygwin:

$ strace bash ./script.sh | grep -c 'fork: 0 = fork()'


One reason for the slow execution of the script are >8000000 context 
switches done by Cygwin.

Bash calls sigprocmask() before starting each command, even for builtin 
commands.
Cygwin's sigprocmask() unconditionally calls sig_dispatch_pending().
This is necessary because POSIX requires that at least one pending 
signal is dispatched by sigprocmask().
sig_dispatch_pending() sends a __SIGFLUSH* to self and this causes 2 
thread context switches: main->sig->main.

With the attached patch, sigprocmask() does nothing if the signal mask 
is not changed.
This reduces the context switches to <5000.
(Patch is only intended for testing, it at least breaks above POSIX rule)


I've run 4 tests scripts on 5 "platforms":

Test 1: Original script, but with [[...]] instead of [...]:

i=1000000
while [[ $i -gt 0 ]]; do
 j=$(((i/3+i*3)**3))
 i=$((i-1))
done

Test 2: Original script unchanged:

i=1000000
while [ $i -gt 0 ]; do
...

Test 3: Original script with /100 iterations and using command version 
of [ (test):

i=10000
while /usr/bin/[ $i -gt 0 ]; do
...

Test 4: A real world "./configure" script


Results on same AMD64 3200+ @2GHz, XP SP2:

|                 Runtime (seconds) of test
|                  1      2       3       4
-------------------------------------------
Cygwin 1.5.24-2   77     84     138      33
Cygwin +patch     38     46     138      33
Linux on Virt.PC: 49     57      62      22
Linux on VMware:  29     34      23      20
Linux native:     23     29       7       6

(Linux = grml 0.9 live CD)

Observations:
- Shell scripts with many builtin commands would benefit from a Cygwin 
optimization preventing unnecessary context switches ...
- ... but this might not help for most real world scripts.
- fork() on Linux is also considerably slower when running in a VM on 
Windows.
- Bash's builtin [[...]] is faster than [...]


Christian


["patch.txt" (text/plain)]

diff -up cygwin-1.5.24-2.orig/winsup/cygwin/signal.cc cygwin-1.5.24-2/winsup/cygwin/signal.cc
--- cygwin-1.5.24-2.orig/winsup/cygwin/signal.cc	2006-07-05 01:57:43.001000000 +0200
+++ cygwin-1.5.24-2/winsup/cygwin/signal.cc	2007-03-07 19:23:27.593750000 +0100
@@ -153,7 +153,6 @@ sigprocmask (int how, const sigset_t *se
 int __stdcall
 handle_sigprocmask (int how, const sigset_t *set, sigset_t *oldset, sigset_t& opmask)
 {
-  sig_dispatch_pending ();
   /* check that how is in right range */
   if (how != SIG_BLOCK && how != SIG_UNBLOCK && how != SIG_SETMASK)
     {
@@ -171,7 +170,8 @@ handle_sigprocmask (int how, const sigse
 
   if (set)
     {
-      sigset_t newmask = opmask;
+      sigset_t oldmask = opmask;
+      sigset_t newmask = oldmask;
       switch (how)
 	{
 	case SIG_BLOCK:
@@ -187,7 +187,11 @@ handle_sigprocmask (int how, const sigse
 	  newmask = *set;
 	  break;
 	}
-      set_signal_mask (newmask, opmask);
+      if (oldmask != newmask)
+	{
+	  sig_dispatch_pending();
+	  set_signal_mask (newmask, opmask);
+        }
     }
   return 0;
 }



--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic