Fandom

Scratchpad

PDQ Manual

215,908pages on
this wiki
Add New Page
Discuss this page0 Share

Ad blocker interference detected!


Wikia is a free-to-use site that makes money from advertising. We have a modified experience for viewers using ad blockers

Wikia is not accessible if you’ve made further modifications. Remove the custom ad blocker rule(s) and the page will load as expected.

Back to Pdq

PDQ User Manual

Updated: Dec 23, 2004

This online edition of the PDQ User Manual is intended to accompany the C language version of PDQ as presented in the book ">The Practical Performance Analyst and corrects several typos found in the original printing.

Overview

PDQ (Pretty Damn Quick) is a queueing model solver, not a simulator. The queueing theory models discussed in Chapters 2 and 3 of The Practical Performance Analyst. are incorporated into the solution methods used by PDQ. This saves you the labor of implementing thos codes each times you construct a queueing model and allows you to concentrate on the accuracy of your model rather than the accuracy of the solutions. PDQ guarantees that for you.


Because PDQ uses algorithmic techniques, rather than an event-based simulation (such as that used by C++SIM, NS, and REAL) it is extremely fast at calculating solutions. It is not too far fetched to say that, the result than it takes to calculate it!


Moreover, PDQ is a flexible library of functions rather than a hard-wired binary application. This flexibility requires that you express your performance model in the C language, and then compile it. Therefore, some programming is required. The good news is, you do not need to learn yet another strange modeling language. The bad news is, you have to learn the programming language called C.


In the spirit of the open-source development model (in fact, before it was even fashionable), PDQ is provided as multiple C source files to enable it to be compiled and used in the environment of your choice - from micros to mainframes.

This philosophy imposes two significant requirements.

System Requirements

You will need access to a C compiler e,g, gcc. Almost by definition, C compilers are available in every UNIX and Linux environment and C packages are now provided with most mainframes. There are also a great many C compiler products available for personal computer operating systems such Linux, DOS, Windows, and MacOS. with a mainframe background) this may appear as a burden. In fact, it greatly enhances the portability of your PDQ models.

Human Requirements

Since the source code provided with the book really constitutes a library of functions for solving performance models, all PDQ models must be written in C. into the C code for your performance model. the constructs of a modern procedural programming language such as: extensible data structures, block coding design, procedure calls, and recursion, to create and solve potentially very elaborate performance models.

All the examples in this book are constructed using this paradigm. Setting up a PDQ model is really quite straightforward. To help you gain familiarity with PDQ, you should first read the section on constructing a [#Simple Example simple example] in this manual. (especially those in Chapters 2 and 3) to get a better idea of some of the variations on coding structure useful for creating and solving a PDQ model.

For those readers not yet familiar with the C language (or C++), PDQ offers another motivation to learn. ANSI standard C programming is authored by Kernighan and Ritchie. Many other excellent introductory texts on the C language are also available.

Remember, serious performance modeling is mostly serious programming.

The PDQ Library

In this section we describe the global variables, public data types, and public procedure calls available in the PDQ_Lib.h file.

Data Types

The following data types (implemented as #defines in the C language) are used in conjunction with PDQ library functions. the synopses of procedures for actual syntax.


  1. PDQ Node Types
    • CEN: Generic queueing center. Used with PDQ_CreateNode</tt>
    • DLY: Generic delay center. Used with PDQ_CreateNode</tt>


  2. Service Disciplines
    • FCFS: First-come first-served. Used with PDQ_CreateNode</tt>
    • ISRV: Infinite server. Used with PDQ_CreateNode</tt>
    • LCFS: Last-come first-served. Used with PDQ_CreateNode</tt>
    • PSHR: Processor sharing. Used with PDQ_CreateNode</tt>


  3. Workload Streams
    • BATCH: A batch class workload which is defined to be one with zero thinktime. Only consistent in the context of a closed queueing circuit to distinguish from TERM. Used with PDQ_CreateClosed</tt>
    • TERM: A terminal class workload which is defined to be one with non-zero thinktime. closed queueing circuit to distinguish from BATCH. Used with PDQ_CreateClosed</tt>
    • TRANS: A transaction class workload which is defined by an arrival rate rather than a thinktime. of a open queueing circuit. Used with PDQ_CreateOpen</tt>


  4. Solution Methods
    • APPROX: Uses the approximate MVA solution technique. for details. Only consistent in the context of solving a closed queueing circuit. An approximation to the EXACT or iterative MVA solution method. Usedwith PDQ_Solve</tt>
    • CANON: Uses the canonical solution technique. See Chapter 2 (and the online PDQ User Manual) for more details. Only consistent in the context of a open queueing circuit. Used as an argument for the PDQ_Solve()</tt> function.
    • EXACT: This solution technique uses the iterative MVA (Mean Value Analysis) method for up to three workload classes in versions of PDQ later than the original release 1.0. Only consistent in the context of a closed queueing circuit. Used as an argument for the PDQ_Solve</tt> function.

Global Variables

The following global variables are mandatory for every PDQ model.


int nodes;

Cumulative counter for the number of nodes returned by

PDQ_CreateNode</tt>


int streams;


Cumulative counter for the number of workload streams returned by P DQ_CreateClosed and PDQ_CreateOpen</tt>


The following global variables may also be useful in PDQ models.


int DEBUG;

Flag to toggle PDQ debug facility. argument to PDQ_SetDebug


char model[MAXBUF];

Character array containing the model name. Initialized via PDQ_Init


MAXBUF = 50
double

Controls the number of iterations used in the APPROXimate MVA solution method.


In addition, the following types (which are actually C structures) retain information about queueing nodes and workloads. See PDQ_Lib.h to see how to de-reference specific fields.


batch_type *bt;

Contains the name and number in this batch class workload together with system statistics.


job_type *job;

Describes the workload type either Terminal, Batch, or Transaction and the queueing circuit type, open or closed.


node_type *node;

Describes the queueing node attributes such as: queue length, utilization, and residence time.


systat_type *sys;

Describes system attributes such as: throughput, and response time.


terminal_type *tm;

Similar to batch_type</tt> but includes thinktime.


transaction_type *tx;

Contains the name of the open circuit workload together with system statistics.


For example, to determine the response time for the third stream of a transaction class workload, the appropriate C construct would be:

job[3].trans->sys->response;</tt>

Functions

All PDQ library functions have a PDQ_ prefix. The following list groups together the PDQ library procedures in the order of their typical invocation:

  1. [#Init PDQ_Init]
  2. [#CreateOpen">PD_CreateOpen] or [#CreateClosed">PDQ_CreateClosed]
  3. [#CreateNode">PDQ_CreateNode]
  4. [#SetDemand">PDQ_SetDemand] or [#SetVisits">PDQ_SetVisits]
  5. [#SetWUnit">PDQ_SetWUnit] [#SetTUnit">PDQ_SetTUnit]
  6. [#SetDebug">PDQ_SetDebug]
  7. [#Solve">PDQ_Solve]
  8. [#GetResponse">PDQ_GetResponse] and/or [#GetThruput">PDQ_GetThruput]
  9. [#GetThruMax">PDQ_GetThruMax]
  10. [#GetLoadOpt">PDQ_GetLoadOpt]
  11. [#GetUtilization">PDQ_GetUtilization] [#GetResidenceTime">PDQ_GetResidenceTime] and/or [#GetQueueLength">PDQ_GetQueueLength]
  12. [#Report">PDQ_Report]

An alphabetically ordered synopsis for each of these functions now follows.


Function Synopses

PDQ_CreateClosed

NAME

PDQ_CreateClosed - define the workload for a closed circuit
queueing
circuit

SYNOPSIS

int PDQ_CreateClosed(char *name, int class, float pop, float
think);

DESCRIPTION

Used to define a workload for a closed circuit queueing model.
separate call is required for workload streams having different
characteristics.

OPTIONS

name: The string used to identify the workload in reports or
debug logs

class: Either TERM, or BATCH type

pop: The number of active user processes in the closed circuit.
This argument is a float to accommodate
57.4 average active users

think: The user delay or "thinktime" before a request re-enters
the queueing system}

RETURNS: the cumulative number of workload streams created.

EXAMPLE

main() {

}

SEE ALSO

PDQ_CreateOpen, PDQ_Init



PDQ_CreateNode

NAME

PDQ_CreateNode - define a queueing service center

SYNOPSIS

int PDQ_CreateNode(char *name, int device, int sched);

DESCRIPTION

Defines a queueing service node for either a closed or
open circuit model.
queueing node.

name: A string used to identify the service node in reports or
debug logs.

device: Type of device.

sched: The queueing discipline.

RETURNS: the the cumulative number of queueing nodes created.

EXAMPLE

main() {

}

SEE ALSO

PDQ_CreateOpen, PDQ_Init


PDQ_CreateOpen

NAME


PDQ_CreateOpen - define an open circuit queueing workload

SYNOPSIS


int PDQ_CreateOpen(char *name, float lambda);

DESCRIPTION


Define a workload in an open circuit queueing model.
call is required for workload streams having different
characteristics.

name: A string used to identify the workload in reports or debug
logs.

lambda: The arrival rate per unit time into the queueing circuit.

RETURNS: the cumulative number of open workloads created.

EXAMPLE


main() {

}

SEE ALSO


PDQ_CreateClosed, PDQ_Init


PDQ_GetLoadOpt

NAME

PDQ_GetLoadOpt - determine the optimal user load

SYNOPSIS


double PDQ_GetLoadOpt(int class, char *wname);

DESCRIPTION


PDQ_GetLoadOpt is used to determine the system throughput for the
specified workload.

class: TERM, or BATCH type.

wname: A string containing the name of the workload.

RETURNS: returns the optimal user load as a decimal number.

EXAMPLE


main() {

}

SEE ALSO

PDQ_GetThruput, PDQ_GetResponse


PDQ_GetQueueLength

NAME

PDQ_GetQueueLength - determine the queue length at a particular device or node.

SYNOPSIS


double PDQ_GetQueueLength(char *device, char *work, int class);

DESCRIPTION


PDQ_GetQueueLength is used to determine the queue length of the
designated service node by the specified workload.
be called after the PDQ model has been solved.

device: A string containing the name of the queueing service node.

work: A string containing the name of the workload.

class: TRANS, TERM, or BATCH type.

RETURNS: returns the queue length as a decimal number.

EXAMPLE


main() {

}

SEE ALSO

PDQ_GetResidenceTime, PDQ_GetUtilization


PDQ_GetResidenceTime

NAME

PDQ_GetResidenceTime - determine the residence time at a particular device or node.

SYNOPSIS


double PDQ_GetResidenceTime(char *device, char *work, int class);

DESCRIPTION


PDQ_GetResidenceTime is used to determine the residence time at the
designated service node by the specified workload.
be called after the PDQ model has been solved.

device: A string containing the name of the queueing service node.

work: A string containing the name of the workload.

class: TRANS, TERM, or BATCH type.

RETURNS: returns the residence time as a decimal number.

EXAMPLE

main() {

}

SEE ALSO


PDQ_GetQueueLength, PDQ_GetUtilization


PDQ_GetResponse

NAME

PDQ_GetResponse - get the system response time

SYNOPSIS


double PDQ_GetResponse(int class, char *wname);

DESCRIPTION


PDQ_GetResponse used to determine the system response time for the
specified workload.

class: TRANS, TERM, or BATCH type.

wname: A string containing the name of the workload.

RETURNS: the system response time as a decimal number.

EXAMPLE


main() {

}

SEE ALSO


PDQ_CreateClosed, PDQ_Init, PDQ_CreateOpen


PDQ_GetThruMax

NAME

PDQ_GetThruMax - determine the system throughput at saturation

SYNOPSIS


double PDQ_GetThruMax(int class, char *wname);

DESCRIPTION


PDQ_GetThruMax is used to determine the system throughput for the
specified workload.

class: TERM, or BATCH type.

wname: A string containing the name of the workload.

RETURNS: returns the saturation system throughput as a decimal number.

EXAMPLE


main() {

}

SEE ALSO


PDQ_GetThruput


PDQ_GetThruput

NAME


PDQ_GetThruput - determine the system throughput

SYNOPSIS


double PDQ_GetThruput(int class, char *wname);

DESCRIPTION


PDQ_GetThruput is used to determine the system throughput for the
specified workload.

class: TRANS, TERM, or BATCH type.

wname: A string containing the name of the workload.

RETURNS: returns the system throughput as a decimal number.

EXAMPLE


main() {

}

SEE ALSO


PDQ_GetResponse


PDQ_GetUtilization

NAME


PDQ_GetUtilization - determine the utilization of a particular device or node.

SYNOPSIS


double PDQ_GetUtilization(char *device, char *work, int class);

DESCRIPTION


PDQ_GetUtilization is used to determine the utilization of the
designated service node by the specified workload.
be called after the PDQ model has been solved.

device: A string containing the name of the queueing service node.

work: A string containing the name of the workload.

class: TRANS, TERM, or BATCH type.

RETURNS: returns the utilization as a decimal fraction in the range 0.0 to 1.0.

EXAMPLE


main() {

}

SEE ALSO


PDQ_GetResponse, PDQ_GetThruput, PDQ_Solve



PDQ_Init

NAME


PDQ_Init - initializes all internal PDQ variables

SYNOPSIS


void PDQ_Init(char *name);

DESCRIPTION


Initializes all internal PDQ variables.
any other PDQ function. It also resets all internal PDQ variables
so that no separate cleanup function call required.
be called an arbitrary number of times in the same model.

name: A string containing the name of the performance model that
will appear in the PDQ report banner.
appearances, the model name should not exceed 24 characters
(including spaces).

RETURNS: None.

EXAMPLE


main() {

}

SEE ALSO


PDQ_Solve, PDQ_Report



PDQ_Report

NAME


PDQ_Report - generates a formatted report

SYNOPSIS


void PDQ_Report();

DESCRIPTION


PDQ_Report generates a formatted report that includes the total
number of nodes and workloads created in the model, system level
performance measures such as throughput and response time for each
workload, and service node performance measures such as node
utilization and queue lengths. A comment field is available to
audit input parameter variations across multiple runs of the same
model.
file named comments.pdq. Sample reports produced by PDQ Reporter
appear throughput this book.

RETURNS: None.

EXAMPLE


main() {




}

SEE ALSO


PDQ_Init, PDQ_Solve


PDQ_SetDebug

NAME


PDQ_SetDebug - enable diagnostic printout

SYNOPSIS


void PDQ_SetDebug(int flag);

DESCRIPTION


Enables diagnostic printout of internal variables and procedures
used in solving a PDQ model.

flag: Set either TRUE or FALSE to toggle the debug facility.

RETURNS: None.

EXAMPLE


main() {

}

Produces the following output.

DEBUG: PDQ_CreateNode




DEBUG: PDQ_SetDemand()

DEBUG: getnode_index()




SEE ALSO


PDQ_Init


PDQ_SetDemand

NAME


PDQ_SetDemand - define the service demand (or service time)

SYNOPSIS


void PDQ_SetDemand(char *nodename, char *workname, float time);

DESCRIPTION


Define the service demand of a specific
workload.
previously. A separate call is required for each workload stream that
accesses the same node.

nodename: the string name of the queueing node.

workname: the string name of the workload.

time: service demand (in units of time) required by the workload
at that node.

RETURNS: None.

EXAMPLE


main() {

}

SEE ALSO


PDQ_CreateClosed, PDQ_CreateNode, PDQ_CreateOpen, PDQ_SetVisits


PDQ_SetTUnit

NAME


PDQ_SetTUnit - change the timebase unit

SYNOPSIS


void PDQ_SetTUnit(char *unitname);

DESCRIPTION


Change the name of the time unit that appears in the PDQ
report.

unitname: a string name of the unit

RETURNS: None.

EXAMPLE


main() {



 }

SEE ALSO

PDQ_Report



PDQ_SetVisits

NAME


PDQ_SetVisits - define the visit count

SYNOPSIS


void PDQ_SetVisits(char *nodename, char *workname,

DESCRIPTION


Used to define the service demand of a specific workload in terms
of the explicit service time and visit count.
workload must exist. A separate call is required for each workload
stream that accesses the same node.
from PDQ_SetDemand in the way node-level performance metrics are
formatted in the PDQ_Report output. The number of visits shows up
in the PDQ_Report INPUTS section. The throughput in the RESOURCE
Performance section shows up as counts per unit time.

nodename: name of the queueing node.

workname: name of the workload.

visits: number of visits to that node. Dimensionless.

service: service time the workload requires at that node (in time
units).

RETURNS: None.

EXAMPLE


main() {

}

SEE ALSO

PDQ_CreateClosed, PDQ_CreateNode, PDQ_CreateOpen, PDQ_SetDemand


PDQ_SetWUnit

NAME


PDQ_SetWUnit - change the name of the workload unit

SYNOPSIS


void PDQ_SetWUnit(char *unitname);

DESCRIPTION


PDQ_SetWUnit changes the name of the work unit that appears in the
PDQ report. The default work unit is Job.

unitname: The name of the work unit.

RETURNS: None.

EXAMPLE


main() {



 }

SEE ALSO

PDQ_Report


PDQ_Solve

NAME


PDQ_Solve - solve the PDQ model

SYNOPSIS


int PDQ_Solve(int method);

DESCRIPTION


PDQ_Solve is called after the PDQ model has been created.
appropriate solution method must be passed as an argument or an
error will reported at runtime.

method: APPROX or CANON.
Note: The EXACT method is highly complex and has not been included
in this version of the PDQ library. See Chapter 3 for more
details.

RETURNS: None.

EXAMPLE


main() {



}

SEE ALSO


PDQ_Report

Simple Example

The following annotated C source code is intended to provide a simple boiler-plate for creating a PDQ performance model. entire model is defined, and solved within the main function. more sophisticated models, it may be preferable to write separate functions to handle different aspects of the model.


Creating the Model

It is a good idea to start the PDQ model off with a unique filename and a description of its purpose. All this goes in a C comment field commencing with /*</tt> and ending with */</tt>.


/*
	
	Illustrate use of PDQ using a single open workload server.
*/


The filename for our model is min_mod.c</tt>.


It is good practice to include the following header files in any PDQ model source code.


#include <stdio.h>
#include <math.h>
#include "PDQ_Lib.h"

main() {

It is necessary to declare the PDQ global variables: nodes and streams. They enable other internal PDQ procedures to keep track of the global state of the queueing circuit created in PDQ.

	extern int	nodes, streams;

Variables that are specific to the model are declared next. In this case, we declare the interarrival time and the service time for the workload.

	float inter_arriv_time = 0.5;
	float service_time = 1.0;


The model is initialized by a call to


PDQ_Init


with the name of the model that will appear in the PDQ report.


The actual PDQ model name that will appear in the PDQ report is

Minimal Model</tt> and need not be the same as the PDQ filename,

although it is a good idea to keep them as similar as possible. We also assign time and work units that are different from the defaults.






The next step is define the queueing centers or nodes that comprise the queueing circuit and the workload that will place service demands on those nodes.




There is only one node and its name is server. circuit model by calling




and passing the workload name work and its interarrival time. This model is an open circuit type.




The service demand placed in the node server by the workload work is defined in the call to





At this point, the PDQ model is now defined and created in memory. All that remains is to solve it and examine the performance data predicted by the PDQ model. the appropriate solution technique is the canonical method.






} /* main */


The report generated by the call to

	PDQ_Report


is annotated in the next section. The C source code for more elaborate PDQ models appear throughout the book.


PDQ Report

This is an annotated version of the report generated for the Minimal Model described in the previous section. includes the PDQ model name, Minimal Model, that was passed as an argument to

	PDQ_Init.

The banner is followed by the comment field (if any has been supplied).



			***************************************
			****** Pretty Damn Quick REPORT *******
			***************************************
			***
			***
			***
			***************************************
			***************************************

			******

I couldn't think of anything to say.


The following section of the report headed: summarizes the number and types of nodes and workloads. case there is only one node and one workload in an open circuit model. Second.


			***************************************
			******
			***************************************

Node Sched Resource
---- ----- --------
CEN

Queueing Circuit Totals:




There are no generators because this an open queueing circuit, not a closed circuit with a finite population generating work. workload and their demands are summarized.


WORKLOAD Parameters

Arrivals
--------
work


The next section , entitled: level and node level performance measures.


			***************************************
			******
			***************************************

Solution Method: CANON


The PDQ report reminds us which of the solution techniques was used in solving the model. In this case, it's the canonical solution.


Each workload component is identified and the system level performance measures are reported that workload component. Minimal Model, there is only one component which was named "work." There is no bounds analysis performed since this is an open circuit model.


		******

Metric
-----------------
Workload: "work"
Mean Throughput
Response Time
Bounds Analysis:
Max Throughput


Finally, node level attribites such as, node utilization and queue length at the node are reported. there is only one node which was named &#223erver" demands placed on it by the single workload component called work.


		******

Metric
---------
Throughput
Utilization
Queue Length
Residence Time


This is the end of the PDQ Report.

Summary

All the examples used throughout the book, are constructed using the PDQ library described in this manual. Minimal Model discussed in this manual, you should turn some of the examples in the text, especially those in Chapters 2 and 3, to get a better idea of how to apply PDQ to the creation and solution of queueing performance model.

Also on Fandom

Random wikia