Subject: DJGPP vs Cygwin
From: CBFalconer <[email-masked]>
To: [email-masked]
Date: Tue, 05 Nov 2002 22:48:56 -0500

I have been using Cygwin to check portability, and recently tried
an experiment.  I compiled and run the same, largely compute
bound, program on both systems and timed their execution.  Both
were compiled with "gcc -W -Wall -O2 -ansi -pedantic -gstabs+",
using gcc 3.1 on DJGPP, and gcc 3.2 on Cygwin.  Both on the
identical machine, running W98.

The program was considerably slower on Cygwin.  The execution
commands were:

timerun a 30000
timerun a 10000    on DJGPP, using 4dos command processor
                   (timerun is an alias, involving timer command)

time ./a 30000
time ./a 10000     on Cygwin, using bash 2.05

I believe the majority of the Cygwin slowdown is due to the slower
loading (although the program is much smaller than under DJGPP)
and slower console output handling.  This is based on the
difference in times between the shorter and longer runs.

FYI the test program was:

/* --- file gaussran.c ---- */
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>

double       vmax, vmin;
double       vamax, vamin;
double       sigma, sigmasq;
unsigned int count, maxinslot;
time_t       seed;
#define AOFFSET 15   /* array[0] <--> value - AOFFSET */
#define SCALE 3

unsigned int distrib[2 * AOFFSET + 1];  /* initialized to 0 */

/* -------------------- */

/* From the C-FAQ, slightly modified */
double gaussrand(void)
{
   static double V2, X;
   static int    phase = 0;
   double        Y, U1, U2, V1, S;

   if (phase) Y = V2 * X;
   else {
      do {
         U1 = (double)rand() / RAND_MAX;
         U2 = (double)rand() / RAND_MAX;

         V1 = 2 * U1 - 1;
         V2 = 2 * U2 - 1;
         S = V1 * V1 + V2 * V2;
      } while (S >= 1 || S == 0);

      Y = V1 * (X = sqrt(-2 * log(S) / S));
   }
   phase = 1 - phase;
   return Y;
} /* gaussrand */

/* -------------------- */

/* maps gaussrand -inf .. 0 into 0..1 and
 *                0 .. +inf into 1..inf.
 */
double gausspos(void)
{
   return exp(gaussrand());
} /* gausspos */

/* -------------------- */

static void plot(int unipolar)
{
   int i, delta;

   if (unipolar) delta = 0;
   else          delta = AOFFSET;
   for (i = 0; i < 2 * AOFFSET + 1; i++) {
      printf("%5.2f (%5d)%*c\n", (double)(i - delta) / SCALE,
        distrib[i], 1 + (int)((300 * distrib[i]) / count), '*');
   }
} /* plot */

/* -------------------- */

static void statistics(double r, int unipolar)
{
   int slot;

   if (r > vmax) vmax = r;
   if (r < vmin) vmin = r;
   if (fabs(r) > vamax) vamax = fabs(r);
   if (fabs(r) < vamin) vamin = fabs(r);
   sigma += r;
   sigmasq += r * r;
   count++;

   r = r * SCALE * (unipolar + 1);
   if (r > 0) r = r + 0.5;
   else r = r - 0.5;

   slot = (int)(r);
   if (!unipolar) slot += AOFFSET;

   if      (slot < 0)           slot = 0;
   else if (slot > 2 * AOFFSET) slot = 2 * AOFFSET;
   ++distrib[slot];
   if (distrib[slot] > maxinslot) maxinslot = distrib[slot];
} /* statistics */

/* -------------------- */

int main(int argc, char **argv)
{
#define DEFAULTLNS 20

   int          i, j, lines;
   double       r;
   unsigned int param1;

   vmax = vamax = sigma = sigmasq = 0.0;
   vmin = vamin = 1e20;
   lines = DEFAULTLNS;
   param1 = count = 0;
   if (argc > 1) {
      srand((seed = time(NULL)));
      param1 = strtoul(argv[1], NULL, 10);
      if (param1 > 1) lines = param1;
   }
   for (i = 0; i < lines; i++) {
      for (j = 0; j < 12; j++) {
         if (argc > 2) r = gausspos();
         else          r = gaussrand();
         statistics(r, argc > 2);
         if (param1 <= 2 * DEFAULTLNS) printf("%6.2f", r);
      }
      if (param1 <= 2 * DEFAULTLNS) printf("\n");
   }
   printf("vmax = %.2f; vmin = %.2f; vamax = %.2f; vamin = %.2f\n"
          "count = %d; sigma = %.2f; sigmasq = %.2f\n"
          "RMS = %.2f; maxinslot = %d peakPCT = %.2f; AVG =
%.2f\n",
           vmax, vmin, vamax, vamin, count, sigma, sigmasq,
           sqrt(sigmasq) / count, maxinslot,
           (100.0 * maxinslot) / count, sigma / count);
   plot(argc > 2);
   if (argc < 2) {
      puts("\nUsage: gaussran [N [anything]]");
      puts("where N is number of sets of 12 samples to take");
      puts("and 'anything' causes unipolar gaussian generation");
      puts("rather than the default bipolar gaussian.\n");
      puts(" Ex: gaussran 1000 p  (for 12000 unipolar samples)");
      puts(" (The detail dump is suppressed for N > 40)");
   }
   return 0;
} /* main */
/* --- end gaussran.c ---- */

-- 
Chuck F ([email-masked]) ([email-masked])
   Available for consulting/temporary embedded and systems.
   <http://cbfalconer.home.att.net>  USE worldnet address!

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Bug reporting:         http://cygwin.com/bugs.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/