Mesquite Software Home
Products / FAQ
Customers
To Order
Contact Us
Site Map
Documentation
News / Events
News & Events

Mesquite Software Newsletter

Volume 6 - Summer 2007

Newsletter Contents
Introduction
Extended Support "Synchronization" Special
CSIM 20 Questionnaire
Ask Herb
Electronic Evaluation Copy of CSIM for Java - Now Available!
Tech Note - Customized Reports with CSIM

Hello, CSIM users,

Once again we greet you with best wishes! It's been a good year for Mesquite so far. We've been busy designing CSIM 20 and have started working on a Student Edition for CSIM for Java. And it's not too late to send us your ideas for either one! In fact, we are actively seeking your CSIM 20 feedback right now!

Mesquite is proud to announce that our founder, Dr. Herb Schwetman, will join a People to People delegation of professionals specializing in Computer Science and Engineering in South Africa in August. The delegation, under the leadership of 2005 IEEE Computer Society President Gerald Engel, will meet with counterparts in Johannesburg and Cape Town to discuss resources, appropriate quality assurance methods and how to address the ethical, social and policy issues raised by the technology. The goal of the delegation is to understand how these issues are addressed in South Africa, what benefits can be gained by collaborations, and how the benefits of these fields can be effectively brought to all of Africa.

We hope this newsletter finds you with exciting summer travel plans and provides enjoyable and educational reading. This issue offers a special deal on Extended Support, requested by many of our larger customers. It also features a technical note on creating customized reports with CSIM and an "Ask Herb" article addressing questions about model size limits. Keep reading to learn more!

return to top


Extended Support "Synchronization" Special

Many companies that use CSIM have Extended Support contracts, purchased over time, that have differing expiration dates.

Several of our large customers have asked to combine all of their Extended Support contracts into a single contract with one expiration date. This structure minimizes paperwork for all, so we wanted to offer it to all of our customers who have more than one Extended Support contract.

From now until September 30th, if you renew all of your contracts at once, we'll give you a 20% discount on all of them *and* pro-rate the time you have on any non-expired contracts. Next year, you'll only need to renew once!

Please contact Mesquite directly to take advantage of this special offer.

return to top


CSIM 20 Questionnaire

We are currently planning for CSIM 20. A critical question we face is which platforms to support. It would really help us if every person reading this Mesquite Software Newsletter would take one minute and giving the following information. Simply cut and paste the questionnaire into the email and let us know your thoughts.

Please email us right away! We'll send the first 100 responders a limited edition Mesquite LED flashlight!

  1. The platform I am currently using for CSIM 19 (or other version) is:
    1. Type of CPU:
    2. Operating System:
    3. Compiler:
    4. Programming Language:


  2. I would like to have CSIM running on another platform (list below):

  3. I would like to see the following features changed in or added to CSIM:

  4. Overall, my experiences with CSIM have been:

  5. Please include your mailing address if you'd like a flashlight (optional):

Thank you very much for your feedback!

return to top


Ask Herb

Occasionally we receive questions from users on topics of interest to the CSIM community. CSIM's founder, Dr. Herb Schwetman, will answer select questions in this newsletter and by email. If you would like to submit a question for Herb, please email him at .

"How big a model can I build with CSIM?" This is a question that a number of users and potential users have asked. It turns out that there are several answers to this question.

First, if you have the Student Edition, there are fixed limits on the number of concurrently active processes, facilities, etc. The values of these limits are not changeable; the model ends if one of the limits is exceeded during the execution of the model.

If you have the Educational Edition or the Professional Edition, these limits are changeable at run time; the changes are effected by calling the "max_" functions. For example, execute a model with 100,000 concurrently active processes, using the function call:

	max_processes(100000);
It will change the limit on processes.

There are a few caveats that should be noted if these max_ functions are called.

  1. If you change the maximum number of facilities, then you must also change the max_number of servers as well. Every facility has at least one server; multi-server facilities can have more than one server per facility.
  2. If you change the maximum number of mailboxes, then you need to increase the maximum number of events as well. Every mailbox has an embedded event.
  3. If your model creates n processes, then your model probably has a few additional processes instantiated. Thus, it is probably wise to "pad" the maximum number of processes in the call to the max_processes() function.

The good news is, subject to other limits imposed by using 32-bit integers and limited amounts of main memory, you can create and execute very large CSIM19 models.

An additional note: Some users have encountered the limitation imposed by using a 32-bit system (in a 32-bit system, they may be limited to a model size of two gigabytes). To circumvent this limitation, Mesquite Software is currently building CSIM 20, which includes versions than can exploit 64-bit systems, such as the new AMD and Intel chips. Stay tuned…

As well, some people have asked, "Why even bother putting limits on processes and simulation objects?" The answer is that in some cases, the fact that a limit is exceeded is a symptom of a bug or an error in the model, and knowing which limit is being exceeded can be a valuable aid in identifying the bug and then correcting the problem. As an example, if the arrival rate at a facility exceeds the service rate, then the queue of waiting customers grows "without bound." In this case, the "max_processes" limit will be exceeded and the model will stop with the "max_processes limit exceeded" error message.

return to top


Electronic Evaluation Copy of CSIM for Java - Now Available!

Have you been waiting to try out CSIM for Java? Now you can download a free evaluation copy and don't have to wait for a CD! You can request a free evaluation copy online of both CSIM for Java and CSIM 19.

To learn more about CSIM for Java, visit www.mesquite.com/csimforjava/. You will also find a complete set of CSIM for Java documentation online at www.mesquite.com/documentation/.

return to top


Tech Note - Customized Reports with CSIM
by Dr. Herb Schwetman

Occasionally, CSIM users want to create customized reports of the output produced by a CSIM model. Examples of these customized reports include

  • Summarizing the results for a series of runs of a model
  • Producing output suitable for input to a spreadsheet
  • Creating reports that can be stored in a database for review in the future.

Fortunately, you can produce any type of output summary or report that is needed. The way to do this is to use the "inspector" functions provided with all of the resource classes and all of the data collection classes.

As an example, we have an M/M/1 queue. An M/M/1 queue is a standard single server queue with exponentially distributed interarrival intervals, exponentially distributed service intervals and one server. It can be thought of as idealized model of a queue of customers buying tickets at a ticket window with one ticket seller.

A CSIM version of this model, shown below, has been modified to create a custom report for each run of the model. In this example, the customized report is produced in place of the standard CSIM report. The new report includes the 90th percentile for the response times. The listing of the C++ procedure, "customReport()," follows:

void customReport()
{
	fprintf(fp, "M/M/1 Queue Report\n\n");
	fprintf(fp, "Mean interarrival interval: %9.3lf seconds\n", IAR_TM);
	fprintf(fp, "Mean service interval:      %9.3lf seconds\n", SRV_TM);
	fprintf(fp, "Server utilization:         %9.3lf\n", f->util());
	fprintf(fp, "Throughput rate:            %9.3lf customers/second\n", f->tput());
	fprintf(fp, "Mean queue length:          %9.3lf customers\n", f->qlen());
	fprintf(fp, "Mean response time          %9.3lf seconds\n", f->resp());
	fprintf(fp, "Response time: 90-th pctl   %9.3lf seconds\n",
               ninetiethPercentileTime(inSystem));
}

This routine makes use of some of the inspector functions provided with the CSIM facility class:

  • facility::util() - the server utilization at the facility
  • facility::tput() - the number of customers completed per second
  • facility::qlen() - the mean number of customers at the facility (both waiting and using the server)
  • facility::resp() - the mean response time per customer

The function, "ninetiethPercentileTime(box *b)," was written to estimate the 90th percentile of the collection of response times (90% of the response intervals are less than this returned value). This routine uses the histogram associated with the time table in the box.

A histogram is a set of buckets collecting counts of values that were observed. Each bucket really corresponds to a range of values. In the example, the histogram for the time table in the box labeled in-system was set up with 200 buckets, with the 0.0 as the value associated with the first bucket and 200.0 as the value associated with the last bucket. The listing for this function follows:

double ninetiethPercentileTime(box *b)
{
	table* t;
	double low, width;
	int num, total;
	int i, sum;
	double res, x;
	
	t = b->time_table();
	low = t->hist_low();
	width = t->hist_width();
	num = t->hist_num();
	total = t->hist_total();
	res = low - width;
	sum = t->hist_bucket(0);
	x = (double)sum/total;
	for(i = 1; x <= 0.9 && i <= num; i++) {
		res += width;
		sum += t->hist_bucket(i);
		x = (double)sum/total;
	}
	return res;
}

This routine gets the contents (count) from each bucket and, using the total number of observations "so far," computes the percent "so far" of the samples. When this percent exceeds 90, the value of the bucket boundary is returned as the 90th percentile.

The custom report produced by these two routines for one run of the model is as follows:

	Mean interarrival interval:     2.000 seconds
	Mean service interval:          1.900 seconds
	Server utilization:             0.948
	Throughput rate:                0.500 customers/second
	Mean queue length:             17.670 customers
	Mean response time             35.374 seconds
	Response time: 90-th pctl      80.000 seconds

The program used in this example actually executes five runs of the model. In each run a different service interval is used. The rerun() function enables the program to invoke an new execution of the model.

We then modified the above example (see end of note for complete program listing) so that the program collects all of the data, with one set of results collected after each run.

The program then produces a single report summarizing all of these results, shown below.

	M/M/1 Queue Report
	
	Mean interarrival interval   2.000
	                                 0      1      2      3      4
	Mean service interval:       0.500  1.000  1.500  1.750  1.900
	Server utilization:          0.249  0.499  0.752  0.877  0.948
	Throughput rate:             0.499  0.505  0.502  0.501  0.500
	Mean queue length:           0.334  1.014  2.969  7.001 17.670
	Mean response time:          0.669  2.010  5.911 13.986 35.374
	Response time 90-th pctl:    1.000  4.000 13.000 31.000 80.000

The complete source code listing below shows the code that saves the results from each run as well as the call to the summary report procedure. This code produces the above summary report.

//	ex2a_sample.h
#include "cpp.h"

class sample_c;
class samples_c;

class sample_c {
public:
	int runNumber;
	double srvTime;
	double utl;
	double tpt;
	double qln;
	double rsp;
	double pct9;
	sample_c *next;
	samples_c *parent;
public:
	sample_c(int rn, double st, double ut, double tp, double ql, double rs, double pc, samples_c *p);
	void setNext(sample_c *s)		{next = s;}
	sample_c *getNext()				{return next;}

};

class samples_c {
protected:
	int numRuns;
	double iarTime;
	sample_c *first;
	sample_c *last;
public:
	samples_c(int nruns, double it);
	~samples_c();
	void addSample(sample_c *s);
	void report();
};

//	ex2a_sample.cpp

#include "ex2a_sample.h"
extern FILE *fp;

sample_c::sample_c(int rn, double st, double ut, double tp, double ql, double rs, double pc, samples_c *p)
{
	runNumber = rn;	// number of the run
	srvTime = st;		// service time
	utl = ut;		// server utilization
	tpt = tp;		// throughput rate
	qln = ql;		// average queue length
	rsp = rs;		// average response time
	pct9 = pc;		// 90th percentile for the response time
	parent = p;
	next = NULL;
}

samples_c::samples_c(int nrun, double it)
{
	numRuns = nrun;
	iarTime = it;
	first = last = NULL;
}

void samples_c::addSample(sample_c *s)
{
	if(first == NULL) {
		first = last = s;
	} else {
		last->setNext(s);
		last = s;
	}
}

void samples_c::report()
{
	int i;
	sample_c *s;

	fprintf(fp, "M/M/1 Queue Report\n\n");
	fprintf(fp, "Mean interarrival interval  %6.3lf\n", iarTime);
	fprintf(fp, "                           ");
	for(i = 0; i < numRuns; i++)
		fprintf(fp, " %6d", i);
	fprintf(fp, "\n");
	fprintf(fp, "Mean service interval:     ");
	s = first;
	while(s != NULL) {
		fprintf(fp, " %6.3lf", s->srvTime);
		s = s->getNext();
	}
	fprintf(fp, "\n");
	fprintf(fp, "Server utilization:        ");
	s = first;
	while(s != NULL) {
		fprintf(fp, " %6.3lf", s->utl);
		s = s->getNext();
	}
	fprintf(fp, "\n");
	fprintf(fp, "Throughput rate:           ");
	s = first;
	while(s != NULL) {
		fprintf(fp, " %6.3lf", s->tpt);
		s = s->getNext();
	}
	fprintf(fp, "\n");
	fprintf(fp, "Mean queue length:         ");
	s = first;
	while(s != NULL) {
		fprintf(fp, " %6.3lf", s->qln);
		s = s->getNext();
	}
	fprintf(fp, "\n");
	fprintf(fp, "Mean response time         ");
	s = first;
	while(s != NULL) {
		fprintf(fp, " %6.3lf", s->rsp);
		s = s->getNext();
	}
	fprintf(fp, "\n");
	fprintf(fp, "Response time 90-th pctl:  ");
	s = first;
	while(s != NULL) {
		fprintf(fp, " %6.3lf", s->pct9);
		s = s->getNext();
	}
	fprintf(fp, "\n");
}

// C++/CSIM Model of M/M/1 queue

#include "cpp.h"			// class definitions
#include 
#include "ex2a_sample.h"
FILE *fp;

const double IAR_TM = 2.0;
const double confidenceLevel = 0.95;
const double relativeError = 0.05;
const double cpuTimeLimit = 120.0;

const int numRuns = 5;
const double serviceTimes[numRuns] = {0.5, 1.0, 1.5, 1.75, 1.90};
double SRV_TM;

facility *f;			// pointer to facility f
box *inSystem;		// pointer to box inSystem
int remainingProcs;		// count of remaining processes

void init();
void initRun();
void generateCustomers();
void customer();
void customReport();
void saveSample(int nrun);
double ninetiethPercentileTime(box *b);

samples_c *samples;

extern "C" void sim(int argc, char *argv[])
{
	int nr;

	init();
	for(nr = 0; nr < numRuns; nr++) {
		initRun();
		SRV_TM = serviceTimes[nr];
		create("sim");
		generateCustomers();
		converged.wait();		// wait for response times to converge
//		report();			// model report
		saveSample(nr);		// custom report
		rerun();
	}
	samples->report();
}

void generateCustomers()
{
	create("gen");
	while(true) {
		hold(exponential(IAR_TM));	// interarrival interval
		customer();			// generate next customer
	}
}

void customer()				// arriving customer
{
	double t1;

	create("cust");

	t1 = inSystem->enter();		// note arrival
	f->use(exponential(SRV_TM));	// use facility
	inSystem->exit(t1);			// note departure
}

void init()
{
	fp = fopen("csim.out", "w");
	set_output_file(fp);
	set_model_name("M/M/1 Queue");
	samples = new samples_c(numRuns, IAR_TM);
}

void initRun()
{
	f = new facility("facility");		// instantiate facility f
	inSystem = new box("in system");		// instantiate box inSystem
	inSystem->add_time_histogram(200, 0.0, 200.0);// add histogram for response time
	inSystem->add_number_histogram(100, 0, 100);// add histogram for qlength
	inSystem->time_run_length(relativeError, confidenceLevel, cpuTimeLimit);
}

void saveSample(int nrun)
{
	sample_c *s;

s = new sample_c(nrun, SRV_TM, f->util(), f->tput(), f->qlen(),
      f->resp(), ninetiethPercentileTime(inSystem), samples);
	samples->addSample(s);
}

double ninetiethPercentileTime(box *b)
{
	table* t;
	double low, width;
	int num, total;
	int i, sum;
	double res, x;
	
	t = b->time_table();
	low = t->hist_low();
	width = t->hist_width();
	num = t->hist_num();
	total = t->hist_total();
	res = low - width;
	sum = t->hist_bucket(0);
	x = (double)sum/total;
	for(i = 1; x <= 0.9 && i <= num; i++) {
		res += width;
		sum += t->hist_bucket(i);
		x = (double)sum/total;
	}
	return res;
}

This note has demonstrated how to use the inspector functions associated with the CSIM classes to create a customized report using the data collected by objects as the model runs. In addition, these functions can be used to extract and save the data to be used in a summary that covers a set of runs of a model. All are examples of how to use the features found in CSIM to tailor CSIM models to meet specific requirements.

return to top

As always, Mesquite would be delighted to hear from you. Please drop us a note or give us a call if you have ideas, comments, or questions. And have a marvelous summer!

Warm wishes,

Nan Schwetman, President
Mesquite Software, Inc.
8500 North MOPAC, Suite 825
Austin, TX 78759, USA
Tel: (800) 538-9153 (US) or +1 (512) 338-9153
Fax: +1 (512) 338-4966
E-mail: nhs@mesquite.com
www: www.mesquite.com

This newsletter is sent to our user community and interested parties by Mesquite Software. You may subscribe by visiting: www.mesquite.com/newsletter/signup.html