//==>>> SOLUTION FOR SUMMER 2013 CAP 4800 PROJECT <<<== file = cluster4.c ===== //= Simple model of a cluster of single server queues (nodes) = //= - Round robin load balancing of requests = //= - Setting number of active servers by a utilization threshold = //= - Read arrival times from a trace file = //============================================================================= //= Notes: = //= 1) Need to set key parameters in #define = //= 2) Adds code to compute 99%-tile = //=---------------------------------------------------------------------------= //= Example execution (for server trace, CSIM report() elided): = //= = //= ============================================================= = //= == *** Model of a cluster of servers *** == = //= ============================================================= = //= = N = 10 nodes = //= = Mu = 5.000000 req/sec = //= = SAMPLE_INTERVAL = 60.000000 sec = //= = LOW_THRESH = 7.100000 % = //= = HIGH_THRESH = 7.200000 % = //= = INCREMENT = 1 = //= = DECREMENT = 1 = //= ============================================================= = //= = Total CPU time = 4.634000 sec = //= = Total sim time = 2579428.218140 sec = //= =------------------------------------------------------------ = //= = >>> Simulation results - = //= =------------------------------------------------------------ = //= = Mean number active = 3.246290 nodes = //= = Mean response time = 0.233915 sec = //= = 50% response time = 0.200000 sec = //= = 98% response time = 0.332041 sec = //= = 99% response time = 0.498199 sec = //= =------------------------------------------------------------ = //=---------------------------------------------------------------------------= //= Build: Standard CSIM build = //=---------------------------------------------------------------------------= //= Execute: cluster4 = //=---------------------------------------------------------------------------= //= Author: Ken Christensen = //= University of South Florida = //= WWW: http://www.csee.usf.edu/~christen = //= Email: christen@csee.usf.edu = //=---------------------------------------------------------------------------= //= History: KJC (05/26/13) - Genesis = //============================================================================= //----- Includes -------------------------------------------------------------- #include "csim.h" // Needed for CSIM stuff #include // Needed for exit() //----- Constants ------------------------------------------------------------- #define N 10 // Number of nodes #define SERVICE_TIME 0.20 // Service time #define TRACE_FILE "trace.dat" // Name of trace file #define MAX_SIZE 10000000 // Maximum size of array X #define SAMPLE_INTERVAL 60.0 // Sample interval for control #define LOW_THRESH 0.071 // Low utilization threshold #define HIGH_THRESH 0.072 // High utilization threshold #define INCREMENT 1 // Increment value #define DECREMENT 1 // Decrement value //----- Globals --------------------------------------------------------------- FACILITY Server[N]; // Server facilities EVENT DoneEvent; // Done event TABLE ActiveTable; // Table of number of active nodes TABLE ResponseTable; // Table of response time int NumActive; // Number of active nodes int CustCount[N]; // Customer count for each node int Count; // Overall customer count double *X; // Time series of response times //----- Prototypes ------------------------------------------------------------ void generate(void); // Generator void control(void); // Control void balancer(void); // Balancer void queue_node(int sta_id); // Queue node int comp(const void *p, const void *q); // Compare p and q for qsort() //============================================================================= //== Main program == //============================================================================= void sim(void) { double lambda; // Mean arrival rate (req/sec) double median; // Median value double percent_98; // 98%-tile value double percent_99; // 99%-tile value int i; // Loop counter // Create the simulation create("sim"); // Malloc space for X X = (double *) malloc(sizeof(double) * MAX_SIZE); if (X == NULL) { printf("*** ERROR - Could not malloc() enough space \n"); exit(1); } // Parameter initializations for (i=0; i>> Simulation results - \n"); printf("=------------------------------------------------------------ \n"); printf("= Mean number active = %f nodes \n", table_mean(ActiveTable)); printf("= Mean response time = %f sec \n", table_mean(ResponseTable)); printf("= 50%% response time = %f sec \n", median); printf("= 98%% response time = %f sec \n", percent_98); printf("= 99%% response time = %f sec \n", percent_99); printf("=------------------------------------------------------------ \n"); report(); } //============================================================================= //== Process to generate customers == //== - Reads interarrival times from a trace file == //============================================================================= void generate(void) { FILE *tf; // Trace file pointer char inString[80]; // Input string double timeStamp; // Delta time in seconds from trace file create("generate"); // Open trace file tf = fopen(TRACE_FILE, "r"); if (tf == NULL) { printf(" >>> ERROR in opening trace file '%s' \n", TRACE_FILE); exit(1); } // Loop to create requests while(1) { // Read and hold for an interarrival time fscanf(tf, "%s \n", inString); if (feof(tf)) break; timeStamp = atof(inString); hold(timeStamp); // Send to load balancer balancer(); } // Out of loop and now set DoneEvent set(DoneEvent); } //============================================================================= //== Process to determine and control how many nodes to use == //============================================================================= void control() { double meanCustCount; // Mean customer count double meanUtil; // Mean utilization for the interval int i; // Loop counter create("control"); // Execute control loop forever while(1) { hold(SAMPLE_INTERVAL); // Determine mean utilization of all nodes meanCustCount = 0.0; for (i=0; i HIGH_THRESH) { NumActive = NumActive + INCREMENT; if (NumActive > N) NumActive = N; } else if (meanUtil < LOW_THRESH) { NumActive = NumActive - DECREMENT; if (NumActive == 0) NumActive = 1; } // Clear the CustCount variable for all nodes for the next iteration for (i=0; i