This is the mail archive of the cygwin mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Cygwin speed


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


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/

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]