I Know What You Did THIS Summer

(Originally posted 2012-09-29.)

Do you see what I did there? 🙂

On March 10th I published the slides to “I Know What You Did Last Summer” on Slideshare. Since then I’ve given the presentation thrice and in the process got to know it a little.

(Yes I really do think creations take on a life of their own, sort of autonomously.) 🙂

So, six months on, I’m very pleased to have been asked to give the presentation again, but there are a couple of extra challenges in there:

  1. It has to fit into 45 minutes, instead of 1 hour+.
  2. It’s got to be sufficiently different to how it was before.

I’ll confess challenge 1 is one I should’ve addressed from the outset: You always have to be able to adapt your material to any timeslot. Yes, I can rip slides out but a “controlled contraction” would be better.

The second challenge is a blessing in disguise. The rest of this post more or less says why – and points the way to some future blog posts…

Much has happened in the past six months, some of which has been remarked upon in this blog. So the new elements I’m going to introduce are:

The second of those I’ve already talked about. The other two belong as blog posts in their own right. Maybe “1 blog post per slide” is a good rule of thumb here.

Two other things have happened in the past six months are:

  • I now have a semi-official part time role in pursuing the case for better instrumentation and talking about what we already have. I’m not sure this should be in the presentation.
  • Talking to several customers and IBM developers through the summer I’m even more sure “Batch Architecture” gleaning is vital to many enterprises. So I ought to emphasise that more.

So, as I say, updating the presentation is something I want to do. And to see if I’ve made a good job of it come along to UKCMG FREE Forum on the 10th October 2012 at The Magic Circle in London.

Some Things You Might Not Know About VSAM SMF Type 64 Records

(Originally posted 2012-09-24.)

This was originally going to be a different post about VSAM’s SMF 64 record, based on a customer situation. But it’s morphed into something else: A round up of "recent" enhancements to the SMF 64 record.

"Recent" is a nice euphemism: Some of these enhancements are 15 years old. 🙂 But let’s start the story at (or at any rate nearer to) the beginning…

Back in the early 1990’s I’d written the kernel of what would become SG24-2557 "Parallel Sysplex Batch Performance". Subsequently a few chums and I started putting together what would become "PMIO" – some tooling around which the Batch Window Tuning offering of the same name was built.

Other people in the team built the VSAM pieces – mostly out of DFSORT steps with assembler E15 and E35 exits, but also SLR as the database and REXX for reporting. Essentially the code marries up SMF 30-4 (step-end), 62 (VSAM OPEN) and 64 (VSAM CLOSE) records.

And it came to pass that I inherited all this code…

I’d not been closely involved with the code before so there was the usual re-engineering effort: Understanding the code, working on the comments and a little reformatting. It’s good code but quite fragile. So the "getting to know you" piece is essential. It’s the same as for any code adoption.

So what has all this got to do with "new" stuff in SMF 64?

If it ain’t broke don’t fix it" applies here – especially given what I said about fragility. So adding stuff that would give additional insight was what drove me to open up the code…

The first thing I added was new with z/OS Release 12: CA (Control Area) Reclaim. There are two fields in support of this line item: They tell me if you’re using CA Reclaim for a VSAM data set and if you’re getting benefit. (Thanks to Scott Drummond for reminding me of this – in the context of my customer’s problem.)

It’s not embarrassing that I’ve only just added this. But here’s one that IS: 🙂 In 1997 in OS/390 Release 4 DFSMS introduced System-Managed Buffering (SMB). This enables you to, for example, enable VSAM LSR (Local Shared Resources) and control it.

(LSR is a big deal as it allows you to change the VSAM buffering scheme to a better one than high-level languages tend to support. Previously one might’ve used the Batch LSR Subsystem to do this.)

So SMF 64 has lots of information on SMB, such as whether the JCL specifies what SMB’s buffering approach will be, whether it leaves it to SMB and what that approach will be (ACCBIAS). And now, only 15 years late, I capture this information: It rounds out what one can say about a VSAM data set’s performance rather nicely.

As for the customer situation: It turns out I mixed up CI (Control Interval) and CA (Control Area) split statistics (I do know the difference) and, wrongly concluded CA splits was a real issue. What I really had was a program-driven load (not a utility) which was causing a huge number of Index CI (write) I/Os. I think the simplest fix for this is to use SMB to turn on LSR buffering with Deferred Write.

It turns out this client is using neither SMB nor CA Reclaim. But if you get to send me your data I will now spot how you’re using these – assuming it’s relevant to the overall story. And we’ll see how well it’s working for you.

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?