#define NO_ZIPF_SPIKE /* * (C)1997 Standard Performance Evaluation Corporation (SPEC) * * This suite contains code acquired from several sources who * understand and agree with SPEC's goal of creating fair and * objective benchmarks to measure computer performance. * * This copyright notice is placed here only to protect SPEC in the * event the source is misused in any manner that is contrary to * the spirit, the goals and the intent of SPEC. * * The source code is provided to the user or company under the * license agreement for the SPEC Benchmark Suite for this suite. */ /***************************************************************** * * * Copyright 1991,1992 Legato Systems, Inc. * * Copyright 1991,1992 Auspex Systems, Inc. * * Copyright 1991,1992 Data General Corporation * * Copyright 1991,1992 Digital Equipment Corporation * * Copyright 1991,1992 Interphase Corporation * * Copyright 1991,1992 Sun Microsystems, Inc. * * * *****************************************************************/ /* * ---------------------- laddis_c_rnd.c --------------------- * * Random number generator. * *.Exported_routines * double Spec_random (RandomState *theState); * long Spec_nrandom (RandomState *theState); * void Spec_srandom (RandomState *theState, int seed); * *.Local_routines * None * *.Revision_History * 06-Nov-05 Convert to Sing# * 24-May-97 Chan-Nui Re-write to make thread-safe * 28-Nov-91 Teelucksingh ANSI C * 01-Aug-91 Wiryaman laddis_srandom() and laddis_random()whee * now use spec_srand() and spec_rand() * instead of srandom() and random(). * 17-Apr-91 Wittle Created. */ /* * Here's the source for the random number generator that SPEC uses. * The function to be called is "spec_rand" which returns an integer * between 1 and MAX_INT-1. * */ /***************************************************************************** * UNIFORM Distribution * *****************************************************************************/ using System; using Singularity.Application.SPECWeb99; //using Microsoft.Singularity.Math; //using Microsoft.Singularity; //using Microsoft.Singularity.Directory; //using Microsoft.Singularity.V1.Services; //using Microsoft.Singularity.Io; #if SINGULARITY using Microsoft.Contracts; #endif namespace Singularity.Application.SPECWeb99.WebFiles { public class Random { public const int A_MULTIPLIER = 16807; public const int M_MODULUS = 2147483647; /* (2**31)-1 */ public const int Q_QUOTIENT = 127773; /* 2147483647 / 16807 */ public const int R_REMAINDER = 2836; /* 2147483647 % 16807 */ /* * Compute the next random number. */ public class RandomState { public int val; public RandomState(int val) { this.val = val; } } public class ZipfState { public RandomState rstate; public int size; public double []table; #if SINGULARITY [NotDelayed] #endif public ZipfState (RandomState rstate, int size) { this.size = size; this.rstate = rstate; table= new double[size+1]; if (table == null) { Console.WriteLine("ZipfState constructor: can't create {0} entries for table", size+1); } } } // ZipfState #if STATIC_NORMAL_DIST public class NormalState { public RandomState rstate; public int size; public int []table; }; #else public class NormalState { public RandomState rstate; public double mean, stddev, y2; public bool use_last; }; #endif public double Spec_random(RandomState /*!*/ theState) /* See "Random Number Generators: Good Ones Are Hard To Find", */ /* Park & Miller, CACM 31#10 October 1988 pages 1192-1201. */ /***********************************************************/ /* THIS IMPLEMENTATION REQUIRES AT LEAST 32 BIT INTEGERS ! */ /***********************************************************/ { int lo; int hi; int test; hi = theState.val / Q_QUOTIENT; lo = theState.val % Q_QUOTIENT; test = A_MULTIPLIER * lo - R_REMAINDER * hi; if (test > 0) { theState.val = test; } else { theState.val = test + M_MODULUS; } return((float) theState.val / M_MODULUS); } /* * Seed the random number generator. */ public void Spec_srandom( RandomState /*!*/ theState, int seed ) { theState.val = seed; } /* * Returns a random number. */ public int Spec_nrandom( RandomState/*!*/ theState ) { Spec_random(theState); return(theState.val); } /***************************************************************************** * ZIPF Distribution * *****************************************************************************/ public ZipfState spec_zipf_setup(RandomState rstate, int size, double Z) { int i; double zipf_sum; ZipfState theState = new ZipfState(rstate, size); if (theState == null) return null; /* compute zipf values for samples 1-n */ for (i = 1; i <= size; i++) { theState.table[i] = Math.Pow(((double)1.0/((double)i)), Z); //theState.table[i] = 1; // SPL TOTAL HACK until POW works!! } /* sum the values so we can compute probabilities. */ /* at the same time, make the values cumulative */ zipf_sum = 0.0; for (i = 1; i <= size; i++) { zipf_sum += theState.table[i] ; theState.table[i] = zipf_sum; } theState.table[size] = 0.0; theState.table[0] = 0.0; /* compute probability values by dividing by the sum. */ /* also reverse the table so we have values starting at 1.0 */ /* and descending to 0.0 (this is what spec_zipf needs) */ for (i = 0; i < size; i++) { theState.table[i] = 1.0 - (theState.table[i]/zipf_sum); } return theState; } private void spec_zipf_free( ZipfState/*!*/ theState) { if (theState.table != null) { theState.table = null; } } public int spec_zipf(ZipfState/*!*/ theState) { double r; int i; #if NO_ZIPF_SPIKE do{ #endif r = Spec_random(theState.rstate); i = 0; while (r < theState.table[i]) { i++; } #if NO_ZIPF_SPIKE } while (i>theState.size); #endif return i-1; } #if STATIC_NORMAL_DIST /* Right now, mean and stddev are ignored. If someone has a good function to generate the cdf for normal distributions, let me know... */ /* size=20, mean = 10, stddev = 3.5, will generate numbers from 0 to 20 */ NormalState spec_normal_setup(, RandomState rstate, double mean, double stddev) { double normal_dist[] = { 0.002137432, 0.005064024, 0.011135458, 0.022750062, 0.043238098, 0.076563771, 0.126549006, 0.19568292, 0.283854542, 0.387548544, 0.5, 0.612451456, 0.716145458, 0.80431708, 0.873450994, 0.923436229, 0.956761902, 0.977249938, 0.988864542, 0.994935976, 1 }; int i, index = 0; theState.size = 1000; theState.rstate = rstate; theState.table=(int *)malloc(sizeof(int)*(theState.size+1)); if (theState.table == NULL) { fprintf(stderr, "spec_normal_setup: can't malloc %d bytes for table\n", sizeof(double)*theState.size); exit (1); } for (i = 0; i < theState.size; i++) { if ((double)i / (double)theState.size > normal_dist[index]) { index++; } theState.table[i] = index; } return theState; } void spec_normal_free(NormalState theState) { if (theState.table) { free(theState.table); } } int spec_nnormal(NormalState theState) { int rval = spec_nrandom(theState.rstate.val); rval = rval % theState.size; return theState.table[rval]; } #else /* Guts of this routine are based on: */ /* boxmuller.c Implements the Polar form of the Box-Muller Transformation (c) Copyright 1994, Everett F. Carter Jr. Permission is granted by the author to use this software for any application provided this copyright notice is preserved. */ private NormalState spec_normal_setup(NormalState/*!*/ theState, RandomState/*!*/ rstate, double mean, double stddev) { theState.mean = mean; theState.stddev = stddev; theState.rstate = rstate; theState.use_last = false; return null; } void spec_normal_free(NormalState theState) { } private double Spec_normal(NormalState/*!*/ theState) { double x1, x2, w, y1; if (theState.use_last ) { /* use value from previous call */ y1 = theState.y2; } else { do { x1 = 2.0 * Spec_random(theState.rstate) - 1.0; x2 = 2.0 * Spec_random(theState.rstate) - 1.0; w = x1 * x1 + x2 * x2; } while ( w >= 1.0 ); w = Math.Sqrt( (-2.0 * Math.Log( w ) ) / w ); y1 = x1 * w; theState.y2 = x2 * w; } theState.use_last = !(theState.use_last); return( theState.mean + y1 * theState.stddev ); } private int spec_nnormal(NormalState/*!*/ theState) { return (int)(Spec_normal(theState)); } #endif } //random } //namespace