Time To Move From zAAPs to zIIPs?

(Originally posted 2012-09-19.)

Prompted by Troy Coleman’s article zEC12 and zIIP Processors I thought I’d write about how I see the future for zAAPs.

First, his article does a good job of covering the area. So I recommend you read it.

Troy mentions the “zAAP on zIIP” function – which allows zAAP-eligible work to run on a zIIP. It’s not news and it’s a good piece of function: It means you can fill zIIPs more readily, making them a better financial proposition than if zAAP-eligible work had to stay on zAAPs, segregated from zIIP-eligible work. The value of this will depend on which of the following three categories your systems are in:

  1. Mostly zIIP-eligible work.
  2. Mostly zAAP-eligible work.
  3. A mixture of both.

I see customers in all three categories. Strictly speaking I should say “systems in all three categories” as this is an LPAR-by-LPAR and machine-by-machine thing. So, to evaluate its applicability you need to use the usual methods (and apply some of the thinking in zIIP / zAAP Capacity Planning).

Troy also quotes the IBM Statement of Direction on the planned relaxation on the use of zAAP-on-zIIP:

IBM plans to provide a PTF for APAR OA38829 on z/OS V1.12 and V1.13 in September 2012 to remove the restriction that prevents zAAP-eligible workloads from running on zIIP processors when a zAAP is installed on the server.

This gives new configuration choices – which ought to be helpful to a number of customers: I can imagine migrations on an LPAR-by-LPAR basis to zAAP-on-zIIP.

He also mentions the Statement of Direction that:

IBM zEnterprise EC12 is planned to be the last high-end System z server to offer support for zAAP specialty engine processors.

So there’s an obvious direction of travel here. All these things taken together suggest the zEC12 timeframe would be a good one to migrate to zIIPs in. Actually I see nothing here that suggests you couldn’t do it on a z196 : Each customer will have their own choreography.

One final thing to watch out for: The configuration rules haven’t changed in that it’s still only one zIIP per GCP (General Purpose CP) and only one zAAP per GCP. There will be relatively few customers who need more zIIP engines on a machine than GCP engines (even with zAAP-eligible workload running on the zIIPs) but I’m sure they do exist. In those cases careful evaluation (particularly of the financial kind) will be the order of the day. And that’s where Capacity Planning, mentioned in my referenced post, comes in.

Games You Can Play With Timestamps

(Originally posted 2012-09-18.)

I’ve written extensively in the past about what you can glean about batch suites from SMF, most notably SMF Type 30.

While I don’t believe SMF alone can give you the full dependency network (complete with validation) I’ve just added some analysis to my code that gets me a little closer. As you’re probably never going to run my code the bit that would be interesting is the kind of inferences it’s now drawing. You might want to duplicate and refine them.

I have a standard report for a suite (a group of jobs with a naming convention) that lists their start and end times (amongst other things). It was written in the mid 1990’s and did just fine for a while. In fact it never broke, it just got underwhelming. 🙂

Looking back at the change log 🙂 I see I made a major enhancement 2 years ago: The code uses Job Identifiers and Reader Start Times to attempt to find jobs released together. Doesn’t work as well as I’d like because it can take more than a second or two for a job to get released so many false negatives occur. But still it reveals (true) stuff.

The latest enhancement attempts to glean something from both start and end times for a stream of jobs:

I’m trying to figure out whether one job follows directly on from the previous one, whether it kicked off in parallel with it, or what.

So here are some tests the code performs, stopping after it satisfies any test.:

  1. If a job starts no more than 5 seconds after the one above AND it starts before the one above finishes then I consider it starting together with it.
  2. If a job starts after the one above finishes but no more than 5 seconds after it finishes I consider it a a follow-on job.
  3. If it starts within the same minute that the one above starts I print an = and not the start time (as that would be tedious and unmnemonic). It might be a co-starter, but it might not.
  4. Otherwise I print the start time as there’s some sort of a gap1.

If you were to ask “is this rigorous?” I’d have to say “no”.

If you were to ask “is it helpful?” I’d say “yes”:

“In tests” 🙂 it’s illuminated what would otherwise be an impenetrable set of start and end times. In other words it’s helping me edge towards a better understanding of a group of jobs.

Now, suppose my code hinted at a dependency – the “follow-on job” case. It wouldn’t explain the dependency2. There are things in SMF that might explain or corroborate a dependency: SMF 14 and 15 for non-VSAM data sets and SMF 62 and 64 for VSAM data sets can be used to understand some dependencies.3 If I see a “follow-on” case I’d be inclined to look at the jobs involved and their access to data sets. I wouldn’t be nearly so rash as to suggest the lack of “data set” dependencies means the jobs could run together.

In fact this illustrates something fundamental about the nature of batch: It’s very fragile and drawing the wrong conclusions is easy to do – with potentially disasterous consequences. Lots of people have started on batch analysis with the “how hard can this be?” attitude and ended up answering that with “it’s actually very hard”. It’s a steep learning curve but do get a helmet, a rope, crampons etc and start the climb. 🙂

With that climbing analogy I should say the point isn’t to reach the top (I don’t feel I have, for instance) but rather to make progress, lots of progress. In that vein, the algorithm I’ve explained above takes me quite a bit further. I hope you find it useful, and maybe you can provide fresh insight: My code continues to evolve as I spot patterns and things, which is exactly the way I like it.


  1. By “gap” I don’t necessarily mean nothing ran but just that no jobs in the suite ran in that gap: In my test case I can see this suite waiting for other suites to get to a certain point.
  2. And nor would the scheduler’s schedule: It just describes the dependencies as the installation saw fit to identify them,
  3. DB2 data access is a notable case where SMF won’t tell you about the dependency.

Another Usage Of Usage Information

(Originally posted 2012-09-13.)

This post is about unusual ways of using the SMF 30 Usage Data information, some of which you’re certain to want if you’re managing z/OS systems’ performance.

A long time ago I noticed character strings in SMF 30 records that looked like product names. (As is my wont I was looking at the raw Type 30 records for a different purpose and spotted them.)

Some time later I figured out these were Usage Data sections. And the strings were indeed product names, but there’s much more besides.

Here’s an example:

Suppose you wanted to know which address spaces were CICS regions. (I do, when conducting a study, but you may feel you already know.) Well, finding address spaces with a program name of "DFHSIP"1 gets you that far. But here’s a nice twist:

Suppose your installation was in transition from CICS 3.2.0 to CICS 4.1.0. Without asking anyone about progress you can use the Usage information: The string

IBM CORP        CICS            V3 R2.0 DFHSIP  5655-M15

tells you all you need to know.2

The same is true for DB2, Websphere MQ, Websphere Application Server, TSO and IMS3, amongst others.

Other companies’ products are represented in the data. In one case the Product Version is "**.**.**". As I mentioned in 3 I think it’s z/OS doing the formatting and in this case overflowing.

By parading IBM products and mentioning other companies’ products I don’t mean to suggest all products use the IFAUSAGE macro to REGISTER. Indeed, support has evolved a little in the products over time. The next example will illustrate this.

Suppose you wanted to know which DB2 subsystem a CICS region connected to, again without asking anyone4:

Recent levels of DB2 will – in their Product Qualifier field show you the subsystem name:

IBM CORP        DB2             9.1.0   DB2T    5635-DB2

But I have at least one set of DB2 Version 8 data without the equivalent of "DB2T" in it. So DB2 has changed to provide more information.

So far my examples have been "online" rather than "batch". They happen to be taken from SMF 30 Interval records (Subtypes 2 and 3). There’s a nice use case for Batch, though:

The Step- and Job-End SMF 30 records (subtypes 4 and 5) also have the product information. If I know a jobstep is “TSO”5 and I want to know if it calls DB2 I can look in the Usage information. Here’s a real Version 8 example:

IBM CORP        DB2             8.1.0   NONE    5625-DB2

Until I was armed with this information I assumed all TSO steps were DB2 steps. In reality they could be something like REXX execs (which most of my programs are). Now, you could use DB2 Accounting Trace (SMF 101) to sort this out – but why bother?

One thing is puzzling me with this data – and at first I thought it was a bug in my code:

I see in at least two cases6 duplicate Usage sections. These aren’t 100% duplicate – the 5 character fields are all the same but the numeric fields differ – but very similar. I saw a CICS region with many dozens of MQ Usage sections. Each had different numeric values. Further, the number of these varies from interval to interval for an address space. An oblique comment I read got me thinking: The comment included the term “TCB”. So I speculate that each of these quasi-duplicate sections represents a TCB or SRB7 or something like that. Can you, dear reader, clear this up?

So those are the things I’ve already figured out I can do with this information. My code at present just works with the Interval records but I can easily extend it to Subtypes 4 and 5. And it only records 4 sections per record. Again I can easily extend it. I pick up the section count, for the reasons outlined above. You might be wondering about the data’s original purpose:

Given that each Usage section includes TCB time and SRB time I would expect people would be using to charge back at two levels:

  • Charging for using a product e.g. DB2 (but probably not down to the subsystem level as that’s a little more obscure).
  • Charging for using a product based on TCB and SRB time.

But that’s just my expectation. I’d like to know what you use the Usage Data section information for, if you do.


  • 1 I’ve already mentioned this in CICS and Batch, What’s In A Name? and He Picks On CICS.
  • 2 This is in fact five adjacent fields in the record – Product Owner, Product Name, Product Version, Product Qualifier and Product Identifier.
  • 3 For IMS Version 11 the Product Version string is an unexpected "V1R1" which leads me to suspect z/OS is doing the formatting.
  • 4 As usual the maxim is "don’t ask people for information you can get from system instrumentation".
  • 5 This would be if the program name was something like “IKJEFT1B”.
  • 6 CICS / MQ and DB2 Stored Procedures.
  • 7 Whether this is a case of “ever existed in the interval” or “existed at the end of the interval” I don’t know.

New Blog Banner – In Honour Of The New zEnterprise EC12 (zEC12)

(Originally posted 2012-09-06.)

I hope you like my new blog banner – in honour of the new zEnterprise EC12.

We actually announced the zEC12 (for short) the day I returned from vacation. Great planning, IBM! 🙂 It’s taken me a while to catch up – and changing the banner was an important step. 🙂

I’ve known about the soon-to-be-announced processor range for quite some time, as I think you’d expect. And tracked what was going to be announced quite carefully. The trouble with tracking something to announcement is you lose some of the “surprise!” factor – which I used to quite like back in my younger days.

I won’t precis the announcement details here. But suffice it to say the zEC12 is improved compared to the z196 in almost every area.1.

You could call it “evolution” rather than “revolution” but there have been a multitude of changes in places that matter. I’d like to highlight, though, a few qualitatively new features:

  • zAware – which runs in a special LPAR and uses analytics capabilities to analyse system messages, providing an almost real time view of systems’ health. It learns from the message traffic patterns, using the information to identify unusual system behaviour and minimise its impact. It’s based on technology from IBM Research.
  • Flash Express – which some people have commented looks like a rerun of Expanded Storage. Personally I’ve seen a number of nasty customer situations where this would’ve really helped out. I’m thinking of when systems have to capture a dump at just the wrong moment – or into already over-committed memory/paging subsystem configurations. I’d like to think it would be equally useful for the happier times, too – such as workload bursts and batch/online transitions.
  • CFLEVEL 18 – which has many enhancements. For me the one that caught my eye was the enhancements to path statistics, externalised through RMF. I’m going to write a post on this some time. (I believe this one, though part of the announcement, is retrofitted to z196. I hope so because I’d like to see customer data with these new fields in from older machines than the zEC12.
  • Transactional Memory – which is aimed at increasing concurrency for applications that use a shared set of data. As we go to higher numbers of processors and degrees of concurrency this sort of thing becomes increasingly important.

This obviously isn’t an exhaustive list but it gives you a flavour: Each new processor range is more than just faster / higher capacity / better environmentals.

For much more detail read the two Redbooks:

The team that wrote these excellent Redbooks includes a number of friends of mine. I found the books a very enjoyable read. Note: They are still in draft.


  1. One exception – which I really don’t think will affect many customers – is maximum memory: It stays at 3TB.

zIIP / zAAP Capacity Planning

(Originally posted 2012-08-04.)

I’m not a capacity planner but I play one on TV1 sometimes.

A customer asked me about the subject of zAAP Capacity Planning so I thought I’d post a few thoughts here. (Almost everything I say here is equally true of a zIIP.)

The main point is I don’t think it terribly different from regular CPU Capacity Planning. But there are some quirks:

  • While we do have queuing we also have Crossover. But at least we have good numbers for the latter.
  • We have numbers for potential use – through the "Project CPU" mechanism.3.

One thing I’ve said consistently since Processor Pools became a meaningful concept (with the advent of ICF4 engines in 1998) is "Report and Manage Processor Pools Separately".

I still think that’s right but there are some considerations with that, most notably in when work eligible for one runs on another:

  1. Crossover – where work that’s eligible on a zIIP or zAAP runs (partially) on a GCP5. These GCPs might well run slower than the zIIPs or zAAPs, of course. And that eventuality is catered for by RMF.
  2. zAAP on zIIP – where zAAP-eligible work runs on a zIIP6
  3. No zIIPs or zAAPs – where work has to run on GCPs instead.

Actually Cases 1 and 3 are quite similar, even if the mechanisms are different.

I’ll confess I took a decision a while back not to become too obsessed by what the various parameters that control crossover actually do. This is because they evolved somewhat over a short period of time. These days I prefer to see what the data says is happening in a given situation and think about how that could be improved. Usually it’s a trade-off between degree of offload to zIIP or zAAP versus responsiveness. (I’ve seen problem cases in both categories.)

At this point I’ll note that I’ve written a lot about zIIPs and zAAPs in the past. Here are the posts that spring to mind…

So, all of the things I’ve talked about are things to bear in mind when doing zIIP and zAAP Capacity Planning, over and above the usual. So let’s talk about “the usual”…

You can readily figure out how much of the zIIP (or zAAP) pool is being used and by which address space. Many exploiters will tell you well below the address space level. For instance DB2 and DDF – using Accounting Trace. And much of that (via PROJECTCPU) is available for currently-running eligible workloads. So current usage is no problem.

Assuming your application isn’t changing its profile of e.g. zAAP vs GCP then forward projection is as it ever was. But, here are two cases where the ratio may well change:

  1. Over time DB2 has changed the way its offload to zIIP function has worked – both eligibilitywise and how it actually distributes the benefit.
  2. If you were to, say, replace JNI methods with native java then the offload proportion would change. In this case for the better. Maybe a different JDBC driver could cause that.7

So the assumption that an application doesn’t change its profile is probably right most of the time, but certainly worth keeping an eye on.

Maybe this post doesn’t answer the original customer’s question directly – but in an informal medium such as this I hope it contributes to the discussion. As I said at the start, this is pretty much “same as it ever was”8 but with a few wrinkles.


  1. Mainly on Channel z2. 🙂
  2. OK I’ve done this joke before: The B-52’s – Channel Z Lyrics
  3. I’m sure I’m stating the obvious when I say that this only works for workloads already running. Other estimation techniques are necessary for fresh ones. The most notable example of this is IPSec which most customers didn’t use prior to the advent of zIIP support.
  4. Internal Coupling Facility, introduced with G5 processors.
  5. General purpose processor.
  6. But only if there are zIIPs but no zAAPs in the processor complex.
  7. I think this happened with Type-2 to Type-4 driver conversions. Someone correct me if I’m wrong, please.
  8. Second song reference in the one post. 🙂

The Low Down on Up Time

(Originally posted 2012-07-10.)

I can tell when a CICS region came up – without looking at CICS-specific instrumentation. What’s more I can repeat the "trick" for any of MQ, DB2, IMS, etc – and so can you.

I’ve just started work on a new piece of reporting. I’ll call it "raddrspc" as that’s the name of the REXX EXEC that I’m writing. It’s about address spaces – most notably long-running ones.

In the mid-1990s when we were building our Batch Tuning offering PMIO, we came up with the term "Job Dossier". I think it was my term, but others in the team reading this are welcome to disagree. 🙂




The idea of a job dossier was to have reporting code put together – in a structured fashion – all the information about a particular batch job we could glean. Essentially from SMF but not necessarily so. I still use job dossiers in my Batch work. But the focus was on timings and things which ended i.e. batch jobs. What I’m starting on is analogous:  a "dossier" of stuff about an address space. Call it an "Address Space Dossier".

The key difference is that I’m interested in interval-level information, rather than events such as data set CLOSEs and steps ending. But I AM interested in events as well. "Interval-level" because I want to apply the Job Dossier idea to things that run for hours, days, weeks or months – such as DB2 subsystems and CICS regions.




It’s been interesting these past few weeks: I’ve been involved in lots of very diverse situations – but they all indicate one thing: It’s time to get nosey about address spaces. And the only way I’m going to do it is if I can write analysis code that makes me quick and aids structured thinking.




SMF 30 Interval records are cut for every address space I’m interested in – so that is a good unifying place to start. I’ll most certainly report on address spaces in an "idealised" way using this data. Then I will detect whether to go down the CICS "leg of the trousers" 🙂 , the DB2 DBM1 one, or whatever. Each of these have their own instrumentation. So if it’s available (for instance DB2 Statistics Trace) I can get specific using it.

There are other sources of information that work for any address space I might be interested in: One is SMF 42-6 Data Set Performance records – also cut on an interval. (Interval proclivities will make this complex, I’m sure.)

But for now, let’s talk about Up Time:




One of the first things I’ve done in raddrspc is extract from SMF 30 Interval records the Reader Start Time (fields SMF30RST and SMF30RSD) for the address space I’m interested in. Because I’m parsing all the interval records for the address space I can see if this changes. In my test case it certainly does: For CICS regions I can see a restart in the middle of my data – which is for a week. I can also see that the previous restart was 24 days before the data starts. And this picture is consistent across all the CICS regions.

So this is not a set of data from a customer who restarts CICS every night. I think that’s a useful nugget of information.

So, in your installation you can conclude similar things – if you don’t know them already.




As I carry on with building raddrspc – which frankly has to be a background activity – I’ll see if there are other pieces of information of similar interest and share them in this blog. I’m sure there will be – because I already know what some of them are.

DSECTs To DFSORT Symbols

(Originally posted 2012-07-07.)

It’s said that imitation is the sincerest form of flattery. In this Social Media age I’d say indirection comes a pretty close second. Indeed there’s a nice term for it: "link love".

Standard advice is not to just post links to the content of others. In reality the word "just" should probably be inserted: Don’t just post links to the content of others.

In that vein I want to point you to Page 9 of Xephon’s MVS Update 199 (April 2003). But I want to give you a little perspective – as my small slice of "value add".

(Before I do I would draw your attention to Xephon’s Copyright notice at the bottom of Page 2. And indeed I intend to stick to it myself.)

Many people alight at this blog after a search for something DFSORT-related: The Referer (sic) URLs tell me that. So I’m going to assume it’s enough to state that DFSORT Symbols allow a record’s structure to be mapped as named fields. You specify these in the SYMNAMES DD with lines like:

XYZZY,27,4,CH             A hollow voice says "Plugh".

This line has five parts:

  • Symbol name – XYZZY
  • Position – 27
  • Length – 4
  • Type – CH
  • Comment –  A hollow voice says "Plugh".

 There are other formats but this post doesn’t require me to describe them.

Contrast that with a DSECT line with similar properties:

XYZZY          DS   CL8        A hollow voice says "Plugh".

One thing that’s missing is the Position (27). It’s implicit from previous statements in the DSECT.

Last week I went through an exercise of converting a DSECT (in fact DFHMNPDA) to DFSORT Symbols – in support of what I described in Another Way Of Looking At CICS Monitor Trace Data. It was a tedious exercise. I did it mostly through mass edits in ISPF. I thought "there has to be a better way", as one does under such circumstances.

My first take was it could be done by having REXX drive HLASM and parsing the output listing. There’s one thing I’ve neglected to mention. It is rather stating the obvious:

HLASM syntax is far more sophisticated than DFSORT Symbols syntax.

So you couldn’t, in general, parse an Assembler deck (in this case a DSECT) and hope to make a good conversion to a DFSORT Symbols deck. A while ago I embarked on this route – after a previous bout of frustration at creating Symbols from a DSECT. It’s the wrong approach.

But getting the Assembler to do the hard work is the right approach.

But friends convinced me – via Facebook 🙂 – that parsing the HLASM output listing is the wrong approach. The information is there but parsing listings with code is just plain miserable – as experiences go. The correct approach is to parse ADATA from HLASM – as it has structured data. Parsing it is a more robust thing to do.

Fortunately, before I had a chance to embark on this (admittedly hobby) project I noticed the Xephon link at the beginning of this post.

I will admit I haven’t even nosed through the listing, yet alone tried the program. I’d assume it’s good – else it wouldn’t’ve been published.

And the reason I’ve not looked at the code is because I may one day want to do something like this and wouldn’t want the copyright issues. Further, I already guess I would want my code to do more. Here’s a for instance:

In the DFHMNPDA DSECT there are numerous XL12 fields. These are STCKE-based fields. As I mentioned in the previous blog post they were widened from 8 bytes to 12 in CICS TS 3.2. My way of processing them is to take bytes 4 to 7 and multiply by 16 to get microseconds. So the DFSORT Symbols that map these 12 bytes will be something like:

SKIP,4
PDRCPUT,4,BI       CPU Time
SKIP,4

I doubt the referenced code would generate that – as it’s pretty specific. If I wrote some code it might well have an option to do that. And there are a number of things I could imagine doing that add value to the basic conversion process – such as generating some diagramming.

Anyhow, give the referenced code a try. I’d like to know how you get on. And if anyone could tell me who wrote the code I’d be glad to acknowledge them here.

Square Roots In DFSORT

(Originally posted 2012-07-02.)

DFSORT’s Arithmetic operators can do many things but the one thing they can’t do is take the square root of a number.

You might think that’s minor but it means you can’t calculate a Standard Deviation. (Variance is fine but dimensionally not so nice when used in conjunction with the Mean.) And I needed Standard Deviation in a real live customer situation.

So I set out to "roll my own". And here’s how I did it…

There is a well known technique for calculating square roots – the Babylonian Method (or Heron’s Method). It’s not terribly advanced maths, frankly: I think I was taught it at about age 14. It goes like this:

  1. Call your number whose square root is to be found a, and pick a first guess for the root. We’ll call this quess x0.
  2. Write x1 = (a + a/x0)/2. In other words xn+1 is the average of a and a/xn.
  3. Iterate until done. We’ll talk about what "done" means later.

As you can see it’s a really very simple method and converges reasonably quickly. And it’s not difficult to program, except for one thing: DFSORT doesn’t have a looping capability. (Yes it loops over the input records, but not in the way I mean.)

Before I show you some code let me talk about some considerations:

  • Because DFSORT’s arithmetic is integer I describe here taking the integer square root of an integer field value. So, for example, it yields sqrt(5)=2.
  • All the arithmetic on the way to finding the root is integer also.
  • The code takes square roots of non-negative integers: No imaginary roots here.
  • The method returns positive roots: As you probably know roots come in pairs, differing only by a sign.
  • The algorithm requires you to provide a first estimate (x0). My first take was a/2. But in the case of a=1 this leads to a root of 0 straightaway – which is particularly unhelpful. So I had to special-case a=1. So the take I went with in the end is x0=a. Not generally a brilliant first guess but avoids the special case.
  • Because this is integer arithmetic completion can’t be only when sqrt(a)*sqrt(a)=a as in most cases this condition isn’t going to be met. Instead I use xn+1=xn as completion: If the two are equal the algorithm isn’t going to produce a different xn+2.

A reasonable question to ask is whether integer square roots are useful…

A standard technique with DFSORT’s Arithmetic operators is to boost the integer values to represent the number of decimal places required. So, for example, to add together 3.14 and 2.72 you’d be storing them as 314 and 272. Then you’d add these integers and use EDIT=(I.TT) to display them as "4.86". So if you wanted to take the square root of 3.1416 you’d multiply by 10,000 and then apply my technique, using EDIT=(IIII.TT) to move the decimal point back.

Structure Of The Example

This is a standard DFSORT invocation. Rather than give you the usual scaffolding I’ll show you the main components:

  • DFSORT Symbols where possible to help keep it clear.
  • COPY (though it could’ve been SORT or MERGE).
  • INREC to parse the free-form input data.
  • OUTREC with multiple IFTHEN clauses to compute the square root.
  • OUTFIL to format the output lines.

You could, in fact, structure this program differently. It might (though I haven’t worked through it) combine everything into a single INREC statement (apart from the COPY specification).

Some Sample Data

In my SORTIN I have the following lines:

100 
5 
1 
27 
3 
4 
999 
999999 
99999999

In other words a single field in each record in EBCDIC (rather than binary) form. (You can generalise all that follows with a small amount of thought.)

(In my test case this is instream data – so it’s fixed-length records and hence no RDW).

Parsing EBCDIC Numbers.

In this simple case I created a set of records with binary representations of the numbers using INREC:

OPTION COPY 
INREC FIELDS=(1,10,UFF,TO=BI)

Here the UFF does the parsing and it parses the 10 bytes starting in position 1, with the output being 4-byte BI fields.

A SYMNAMES Deck To Simplify Things

You may know you can define symbols with DFSORT. Here’s the deck I used in this example:

//SYMNAMES DD *
INPUT,1,4,BI 
SQRT,*,4,BI 
PREV,*,4,BI 
/* 

(You’ll want a SYMNOUT DD to go with it.)

  • INPUT maps the integer value created by INREC. It’s a, the number whose square root we’re seeking.
  • SQRT maps the field where successive estimates of the root are stored.
  • PREV maps the field where the previous estimate is stored – so we can tell if an iteration has changed the estimate of the root.

Taking The Square Root

In my example all the work is done in a series of IFTHEN clauses in an OUTREC statement:

  1. A single WHEN=INIT clause initialises the estimate (SQRT) and clears the previous estimate (PREV).
  2. Repeated WHEN=(SQRT,NE,PREV) clauses compute successive approximations – but only if the last two estimates weren’t the same.

Here’s the code:

   OUTREC IFTHEN=(WHEN=INIT, 
       OVERLAY=(SQRT,INPUT,X'00000000')), 
     IFTHEN=(WHEN=(SQRT,NE,PREV),HIT=NEXT, 
       OVERLAY=(PREV:SQRT,SQRT:(SQRT,ADD,(INPUT,DIV,SQRT)),DIV,+2,
         TO=BI,LENGTH=4)), 
     IFTHEN=(WHEN=(SQRT,NE,PREV),HIT=NEXT, 
       OVERLAY=(PREV:SQRT,SQRT:(SQRT,ADD,(INPUT,DIV,SQRT)),DIV,+2,
         TO=BI,LENGTH=4)),
         
         ...
          
     IFTHEN=(WHEN=(SQRT,NE,PREV),HIT=NEXT, 
       OVERLAY=(PREV:SQRT,SQRT:(SQRT,ADD,(INPUT,DIV,SQRT)),DIV,+2,
         TO=BI,LENGTH=4))

This you’ll recognise as an unrolled loop. The "…" says you can repeat the previous IFTHEN clause as many times as you like.

A good question would be "how many times?" I found good convergence after 15. For example, the 99999999 value went to 10028 in 15 iterations and 10000 in 16. You could pick 20 and be sure of getting an accurate value.

Let’s talk about control flow through the queue of IFTHEN clauses…

  • The WHEN=INIT is always executed.
  • HIT=NEXT on a WHEN=(logexp) clause means "even if this test succeeds proceed to the next WHEN=(logexp) clause having executed this one’s OVERLAY".
  • Even if a WHEN=(logexp)’s logical expression is false all subsequent WHEN=(logexp) clauses are processed – even if, as in this case, they’ll evaluate to false. So this isn’t really a "WHILE(logexp) DO … END" construct (but you can construct the logexp so it works that way).

In the past I’ve likened multiple IFTHEN clauses to a pipeline. This example shows why.

Printing The Results

The following is a quite complicated piece of report formatting. Its aim is to format numbers and then squeeze out the resulting leading blanks. At the same time it has to preserve blanks in text.

OUTFIL IFTHEN=(WHEN=INIT, 
    BUILD=(C'x=',INPUT,EDIT=(IIIIIIIIIIT), 
      C'_sqrt(x)=',SQRT,EDIT=(IIIIIIIIIIIT), 
      C'_sqrt(x)*sqrt(x)=',SQRT,MUL,SQRT,EDIT=(IIIIIIIIIIIT),
      C'_prev_est=',PREV,EDIT=(IIIIIIIIIIIT))), 
  IFTHEN=(WHEN=INIT, 
    BUILD=(1,90,SQZ=(SHIFT=LEFT,PAIR=QUOTE))), 
  IFTHEN=(WHEN=INIT, 
    FINDREP=(IN=C'_',OUT=C' ')) 

Let’s examine it more closely:

  • The first WHEN=INIT takes four numbers and formats them:

    • The number we wanted to find the square root of,
    • The square root,
    • What happens when you square that back up again,
    • The previous estimate of the square root.

    These are formatted with leading zeroes turned into blanks and some text is wrapped around them (with underscores standing in for blanks).

  • The second WHEN=INIT squeezes all the blanks out. This is why I used underscores in the wrapping text.

  • The third WHEN=INIT turns all the underscores into blanks.

Output Using The Sample Data

The output below isn’t particularly pretty. I wanted to use the OUTFIL code I’ve shown you to demonstrate the ability to selectively squeeze blanks out.

x=100 sqrt(x)=10 sqrt(x)*sqrt(x)=100 prev est=10                 
x=5 sqrt(x)=2 sqrt(x)*sqrt(x)=4 prev est=2                       
x=1 sqrt(x)=1 sqrt(x)*sqrt(x)=1 prev est=1                       
x=27 sqrt(x)=5 sqrt(x)*sqrt(x)=25 prev est=5                     
x=3 sqrt(x)=2 sqrt(x)*sqrt(x)=4 prev est=1                       
x=4 sqrt(x)=2 sqrt(x)*sqrt(x)=4 prev est=2                       
x=999 sqrt(x)=31 sqrt(x)*sqrt(x)=961 prev est=31                 
x=999999 sqrt(x)=999 sqrt(x)*sqrt(x)=998001 prev est=1000        
x=99999999 sqrt(x)=10028 sqrt(x)*sqrt(x)=100560784 prev est=10784

Although this has been quite a complex post I hope it’s taught you a few new DFSORT tricks. Actually, the “meat” of it is the Square Root calculation – which I’m using “in anger” (AKA “for real”) right now. And the technique should be readily adaptable.

The question is: Are there other Newton-Raphson-style computations worth doing?

Another Way Of Looking At CICS Monitor Trace Data

(Originally posted 2012-06-30.)

The CICS Monitor Trace SMF Record (Type 110) has got to be one of the most complicated SMF records in existence – and for good reason.

Which is precisely why I’m not going to attempt to process the raw records in my code. (And why PMCICS doesn’t support releases after a certain point.)

But the "and for good reason" hints at the fact I think this is a tremendously valuable type of instrumentation – because it goes down to the individual transaction instance level.

You’ll have seen from He Picks On CICS I think CICS is a very interesting product to work with, performancewise. (And one day soon I hope to get to play with it from an Application Programming perspective.)

In that post I briefly mentioned CICS Performance Analyzer (CICS PA) – which I’ve spent a lot of time with recently. I like it a lot and the reports (and CSV files) it produces have been very helpful. Not least because it helps sort out the nested components of transaction response time.

In this post, however, I want to outline another approach. If you don’t have (and can’t get) CICS PA this might help you. It might also inspire you if you want to do some custom reporting that CICS PA doesn’t do. (In skilled hands maybe CICS PA will do what my experiment below did. If so it’ll probably do it better.) This approach is to use standard CICS tools and DFSORT to process individual 110 records…

Standard CICS Tools

I’m using two CICS tools. They are both distributed in the SDFHLOAD load library, so if you have CICS you have them. They are:

  • DFHMNDUP – which creates CICS Dictionary records, essential to processing Monitor Trace records. This is in SDFHLOAD but not SDFHSAMP but I actually don’t need to know how it works or to modify it. It’s A Kind Of Magic 🙂
  • DFH$MOLS – which reads (and decompresses) Monitor Trace records and provides a sample report. It also can create a one-output-record-per-input-record data set. It is in SDFHSAMP – which proved crucial as I needed to know how it works.

DFSORT

We all know (and I hope love 🙂 ) DFSORT and ICETOOL.


Putting It All Together

DFH$MOLS needs Dictionary Records for every CICS region – because these records tell it how to process the records. Because you can tailor Monitor Trace records from a region using its Monitor Control Table (MCT) DFH$MOLS can’t assume they’re in a totally standard format. (Actually I see fewer customers tailoring their MCTs, perhaps because there’s less emphasis on space minimisation.) I said at the outset the record is complicated and this is part of the good reason why.

So, prior to running DFH$MOLS I ran DFHMNDUP once for each CICS region. (From Type 30 I already know the jobnames for the regions and the CICS region names happen to be the same – as is often the case.) Though you can feed in the MCT for a region I didn’t need to – because the set of data I’m working with is from a customer who doesn’t tailor their MCTs. So I ended up with five Dictionary Record data sets – each with one record in. (This customer has a single TOR, three AORs and a FOR.)

When running DFH$MOLS I concatenated these five Dictionary Record data sets ahead of the Monitor Trace data set. You have to do it in this order so the Dictionary Record for a region precedes all the Monitor Trace ones for the same region.

While DFH$MOLS can produce formatted reports I wanted to create raw records with the fields in fixed positions. (You can tell where this is headed.) So I specified UNLOAD LOCAL. The "LOCAL" is quite important: It ensures timestamps are in the local timezone. Otherwise timestamps are in GMT. (I actually did go down this "blind alley" first time round.)

Processing was surprisingly swift and the end-result was a data set with records reliably laid out the way I needed them: I’m out of the game of worrying about record formats and record compression etc. Result! 🙂

The goal of  this experiment  was to produce a file with one record per minute – for a single transaction in a single region. The record contains three pieces of information:

  1. Time of the minute – e.g. "15:30".
  2. Transactions per second – averaged across that minute.
  3. Average response time – in milliseconds.

In fact I could’ve formatted these all differently (and summarised differently). So I could’ve used tenths of milliseconds (almost standard – "decimils" or "hectomics"?) and summarised by the second, as two examples.

As I mentioned before I needed to understand some aspects of how DFH$MOLS works – so I read the Assembler source. I’ll admit to not being very familiar with the details of Insert Under Mask (ICM) but it turned out to be important…

The response time for a transaction is given by subtracting the raw record’s start and end times – according to the code. These turn out to be the middle 4 bytes of a STCK (not "E") value. Following the chain of logic further back – and I won’t bore you with the details – it turned out the value is in 16 microsecond units. With DFSORT Arithmetic operators it’s easy to translate that into milliseconds – but best done after summing and piding by the number of transactions.

The timestamp for a transaction is of the form X’02012100′ followed by a value in hundredths of seconds. Again quite easy to turn into something useful in DFSORT. (This time I didn’t need the DFH$MOLS source to tell me this – I browsed the DFH$MOLS output in Hex mode and it was readily apparent.) As I said before my first go was without the "LOCAL" option so the timestamps were from a different time of day and it was obviously GMT. With "LOCAL" I could see it all coming right.


There Be Dragons

The above is quite straightforward – even if the bits about ICM and timestamps left you cold. 🙂 But there are some issues worth noting…

I used the CICS 650 (externally TS 3.2) libraries. This was fine as the records are from TS 3.2 CICS regions. This isn’t generally a stable thing to do – as everything in the process could change from release to release. So run the right DFHMNDUP – if you need that step. Also run the right DFH$MOLS.

In CICS TS 3.2 timestamp fields were widened from 8 bytes to 12. As this web page says DFH$MOLS got it right and the UNLOAD format is still the same as before. Critical, therefore that you have the right DFH$MOLS release.

While I don’t expect the timestamps to get widened again any time soon, there might be further similar changes going forwards. So, to repeat, make sure you’re using the right DFH$MOLS (and DFHMNDUP).

I’m sure there are other dragons but they haven’t singed my cardie yet. 🙂


What Next?

I started to create a DFSORT Symbols mapping of the output of DFH$MOLS UNLOAD but – for reasons of time – only managed to get the first few dozen fields mapped. Sufficient to do my "day job". I could extend that – and it might make a nice sample.

I could publish my DFSORT experimental case as a sample – possibly building on  the Symbols deck. I could try and keep track of the twists and turns of the UNLOAD records – using (for example) IFTHEN processing. I’m really not missioned to do that. 😦

I could develop some more examples. Again, I’m not missioned to do that. 😦

I hope this post has encouraged some of you to experiment with this approach.

What I’m going to really do next is explain the following:

For the first 45 minutes or so the transaction rate stays more or less constant but the response time is all over the place, including some minutes where it spikes to huge (but realistic) values. Then, suddenly, the response time settles down to a low value – and the transaction rate remains more or less the same as it was before. And stays that way to the end of the data.

I think I have an explanation: From RMF I can see certain things awry until about that point (with the standard 15-minute granularity). To really explain it at the transaction level would take a more detailed analysis. Fortunately I can do this with the DFH$MOLS output. And CICS PA has already told me which fields are likely to be the most useful…

Two Kinds Of Pipes

(Originally posted 2012-06-24.)

It’s been a while since I last posted here. And that’s been more a matter of being incredibly busy than anything. Some of you will have seen me "on stage" – there having been several conferences and user groups recently. Some of you were with me at the zChampions meeting and some of you I’m actively working on customer situations with.

(By the way one of the rules of zChampions isn’t "nobody mentions zChampions". 🙂 But it’s true to an extent that "what happens at zChampions stays in zChampions”. 🙂 But only to an extent.)

I won’t signal a let up in activity by suggesting I’ll post more frequently: That’s probably unrealistic.

But in this post I want to talk about z/OS Unix Pipes in JCL vs BatchPipes/MVS. The reason for doing this is that in some circumstances z/OS Unix Pipes in JCL can play a similar role to BatchPipes. But there are caveats. In what follows I’ll generally use the term “Unix Pipes” 1 as shorthand for “Unix Pipes in JCL” (except for the next heading where I think it’s clearer to write it in full).

Unix Pipes in JCL

Here are two sample pieces of JCL you can play with:

First a writer job. Let’s call it "W":

//WRITE1  EXEC PGM=IEBGENER 
//SYSPRINT DD SYSOUT=K,HOLD=YES 
//SYSIN   DD DUMMY 
//SYSUT1  DD * 
ABCD 
/* 
//SYSUT2  DD PATH='/u/userhfs/pmmpac/pipe1',DSNTYPE=PIPE,
//        LRECL=80,BLKSIZE=3200,RECFM=FB, 
//        PATHOPTS=(OWRONLY,OCREAT), 
//        PATHMODE=(SIWUSR,SIRUSR), 
//        PATHDISP=(DELETE,DELETE) 

And now a reader job ("R"):

//READ1   EXEC PGM=IEBGENER 
//SYSPRINT DD SYSOUT=K,HOLD=YES 
//SYSIN   DD DUMMY 
//SYSUT1  DD PATH='/u/userhfs/pmmpac/pipe1',DSNTYPE=PIPE,
//        LRECL=80,BLKSIZE=3200,RECFM=FB, 
//        PATHOPTS=(ORDONLY,OCREAT), 
//        PATHMODE=(SIWUSR,SIRUSR), 
//        PATHDISP=(DELETE,DELETE) 
/* 
//SYSUT2  DD SYSOUT=K,HOLD=YES 

The pipe here is given by the PATH name “/u/userhfs/pmmpac/pipe1” (and you’ll have to figure out what it should be in your environment).

In this example I’m just copying from instream data (the “ABCD” line) to the pipe and copying from the pipe to the SPOOL. Simple stuff you can get working and build on.

I experimented with PATHOPTS, PATHMODE and PATHDISP and the ones in the sample JCL decks are the ones that worked best. In particular PATHDISP=(DELETE,DELETE) seemed to be necessary to get the pipe deleted after use.

When I run these they appear to perform as a BatchPipes/MVS pipe would: Overlapped and apparently without real I/O2 – which are the key benefits.

To those who know BatchPipes/MVS this should all look quite familiar…

Unix Pipes vs BatchPipes/MVS

As I said, they’re quite similar. But there are differences that are worth noting. The most notable ones are:

  • While BatchPipes can “add value” with fittings in the pipe-end definitions Unix Pipes can’t – you’d have to have a separate intermediary job (I tend to call “F” for “Filter” / “Fitting”. You can write it in whatever you like. Suggestions?
  • You don’t get the equivalent of SMF 91 – which has handy things to enable you to e.g, balance the pipe.
  • You don’t have a subsystem – and that’s probably a good thing. Instead you’re using the Unix file system – as the pipe name suggests.
  • To convert a non-piping usage to a piping one requires significantly more JCL “surgery”. In particular you can’t use the data set name for the pipe name. And you can see things like DISP are completely different. So it’s more work.
  • BatchPipes/MVS has the BatchPipePlex capability to pipe between Parallel Sysplex members using Coupling Facility structures. I don’t think you can do anything like that with Unix Pipes.

There are probably other differences but these are the most noteworthy to me – as someone who’s a lot of experience with BatchPipes/MVS. Some of them definitely can be worked around – such as the lack of Fittings support. Some of them are more difficult. But if you just want a simple inter-job piping capability have a go with Unix Pipes – perhaps starting with the two JCL samples above. And one key advantage of this approach might be that it’s free and available to all (I think) – so long as your jobs are allowed to use Unix System Services3.

And as to posting frequency: I feel under no pressure to publish – whether timing-wise or content-wise. If there’s stuff I think is interesting (and not damaging to a client) you’ll see it here – when I get the chance.


1 Yes, I know Unix shells have their own built-in piping capabilities. Discussing those is beyond the scope of this post.

2 I’m told no Unix piping implementation would perform physical I/O – so this isn’t a queue on disk (with the issues that would raise: I/O time and potential physical limits).

3 And I note the perpetual discussion on the IBM-MAIN Listserver group about whether “USS” is an acceptable abbreviation for “Unix System Services”… 🙂