#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 Re-write to make thread-safe // 28-Nov-91 ANSI C // 01-Aug-91 laddis_srandom() and laddis_random() // now use spec_srand() and spec_rand() // instead of srandom() and random(). // 17-Apr-91 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