delorie.com/archives/browse.cgi   search  
Mail Archives: cygwin/2007/03/07/15:14:09

X-Spam-Check-By: sourceware.org
Message-ID: <45EF1CED.608@t-online.de>
Date: Wed, 07 Mar 2007 21:13:33 +0100
From: Christian Franke <Christian DOT Franke AT t-online DOT de>
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.1.2pre) Gecko/20070111 SeaMonkey/1.1
MIME-Version: 1.0
To: cygwin AT cygwin DOT com
Subject: Re: Cygwin speed
References: <45E86FFD DOT 7060301 AT princeton DOT edu> <45E876FA DOT 7401B017 AT dessent DOT net> <20070305011713 DOT GG6734 AT ns1 DOT anodized DOT com>
In-Reply-To: <20070305011713.GG6734@ns1.anodized.com>
X-ID: VsDEOMZJZeuGNpPAnzVh5gAs90-WzrmorjmlqVnDwwaAmGxxF2I2Qd
X-TOI-MSGID: c8d436eb-f538-4661-97e9-c9d4c196bc6b
X-IsSubscribed: yes
Mailing-List: contact cygwin-help AT cygwin DOT com; run by ezmlm
List-Id: <cygwin.cygwin.com>
List-Subscribe: <mailto:cygwin-subscribe AT cygwin DOT com>
List-Archive: <http://sourceware.org/ml/cygwin/>
List-Post: <mailto:cygwin AT cygwin DOT com>
List-Help: <mailto:cygwin-help AT cygwin DOT com>, <http://sourceware.org/ml/#faqs>
Sender: cygwin-owner AT cygwin DOT com
Mail-Followup-To: cygwin AT cygwin DOT com
Delivered-To: mailing list cygwin AT cygwin DOT com

--------------080503080008000005090109
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit

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


--------------080503080008000005090109
Content-Type: text/plain;
 name="patch.txt"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="patch.txt"

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;
 }


--------------080503080008000005090109
Content-Type: text/plain; charset=us-ascii

--
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/
--------------080503080008000005090109--

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019