356 lines
11 KiB
C#
356 lines
11 KiB
C#
|
#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
|