Once you’ve downloaded PDQ with a view to solving your performance-related questions, the next step is getting started using it. Why not have some fun with blocks? Fun-ctional blocks, that is.
Since all digital computers and network systems can be considered as a collection of functional blocks and these blocks often contain buffers, their performance can be modeled as a collection of buffers or queues. Therefore, start developing your PDQ model by drawing a functional block diagram of the relevant architecture using elements like these:
The objective is to identify how much time is spent at each stage or block as it processes the workload of interest. Ultimately, each functional block becomes converted into a queue subsystem like those shown above. This includes the ability to distinguish sequential and parallel processing. In the language of PDQ, a queue is created using a call to either CreateNode or CreateMultiNode.
Here’s how the above blocks would appear in PDQ in R as three separate models in the same R script:
<br /># PDQ fun blocks<br /># Created by NJG on Mon Aug 30 2010<br /><br />library(pdq)<br /><br />work <- "Requests"<br />arate <- 0.75<br />Ta <- 0.25<br />Tb <- 0.75<br />p <- 0.5<br /><br />Init("Sequence Fun Blocks")<br />CreateOpen(work,arate)<br />CreateNode("SeqBlock",CEN,FCFS)<br />SetDemand("SeqBlock",work,Ta+Tb)<br />Solve(CANON)<br />Report()<br /><br />Init("Parallel Fun Blocks")<br />CreateOpen(work,arate)<br />CreateNode("ParaBlock1", CEN,FCFS)<br />SetDemand("ParaBlock1",work,p*Ta)<br />CreateNode("ParaBlock2",CEN,FCFS)<br />SetDemand("ParaBlock2",work,(1-p)*Tb)<br />Solve(CANON)<br />Report()<br /><br />Init("Repetition Fun Blocks")<br />CreateOpen(work,arate)<br />CreateNode("RepBlock",CEN,FCFS)<br />SetDemand("RepBlock",work,Ta/(1-p))<br />Solve(CANON)<br />Report()<br />Notice that each PDQ model is essentially just a list of queues. That’s really all a PDQ model is: work name, queue name, service time, repeat. When all the queues (blocks) are listed, just Solve it.
We can easily check the output of the “Sequence Fun Blocks” model. Since the combined service demand equals 1.0 second and the arrival rate is 0.75 per second, the residence time (R) had better be R = 1/(1 – (3/4)) = 4 seconds. And indeed, the RESOURCE Performance section of the PDQ Report reveals that to be correct.
<br /> ****** RESOURCE Performance *******<br /><br />Metric Resource Work Value Unit<br />------ -------- ---- ----- ----<br />Throughput SeqBlock Requests 0.7500 Trans/Sec<br />Utilization SeqBlock Requests 75.0000 Percent<br />Queue length SeqBlock Requests 3.0000 Trans<br />Waiting line SeqBlock Requests 2.2500 Trans<br />Waiting time SeqBlock Requests 3.0000 Sec<br />Residence time SeqBlock Requests 4.0000 Sec<br />The online PDQ manual contains more information about PDQ functions. Models of this type are developed as an iterative process. Do not expect to get everything correct and validated in a single pass. That never happens and if it does, you probably made a mistake in understanding either the PDQ model or the measurements used to parameterize the PDQ model. On the other hand, the good news is that you can start with almost any preliminary sketch of the functional blocks and converge to a more accurate PDQ model over time.
Other diagrammatic techniques e.g., UML diagrams, may also be useful but I don’t understand that stuff so I’ve never tried it. If anyone does try that approach I’d be interested to hear about it.
See Chap. 6 “Pretty Damn Quick(PDQ)—A Slow Introduction” in my Perl::PDQ book for more ideas.