Understanding zIIP Usage in CICS
How to understand your zIIP usage in CICS.
By Ian Burnett01/01/2019
In z/OS*, usage costs are derived from general-purpose CPU consumption, which is measured in millions of service units (MSUs). CPU consumption is aggregated on a continual basis to produce a four-hour rolling average (4HRA) metric, which helps determine the total software cost of the environment.
IBM z Integrated Information Processors (zIIPs) allow clients to purchase additional processing power without affecting the total MSU rating or machine model designation. Because IBM doesn’t impose IBM software charges on zIIP capacity, offloading the execution of application code from CPUs to these specialty zIIP engines can reduce 4HRAs and overall software costs.
The easiest way to allow applications to exploit these zIIP engines is to use Java*, executing the compiled code within a JVM. As a multilanguage application server, CICS* Transaction Server for z/OS is an ideal hosting environment. It offers tight integration between programs implemented using any of the languages supported by CICS—including COBOL, PL/I, C, Assembler and Java.
Within z/OS, eligibility for offloading to a zIIP engine is determined on a per-task control block (TCB) basis. At any given point in time, an executing TCB is classified as either zIIP eligible or not zIIP eligible. The eligibility status of the TCB may change many times throughout its lifetime. While many circumstances may qualify a TCB as being zIIP eligible, I’ll be concentrating on the primary use case in CICS: Java applications using a JVM.
In z/OS, any Java code running within a JVM is eligible for offload to a zIIP engine. This eligibility not only includes your application code, but also extends to any third-party Java packages, as well as the base Java libraries.
When running within the CICS environment, a JVM instance resides within the CICS address space and accesses CICS functions using native (i.e., non-Java) calls. To access the CICS functions, Java programmers are provided with their own version of the CICS API: JCICS.
Starting in the Java application, the executing TCB runs within the JVM and is therefore classified as zIIP eligible. The application invokes a CICS function using the JCICS API: a set of Java classes shipped with the CICS runtime. These classes pass control from Java code into native code, across what’s known as the Java Native Interface (JNI). Now that execution has passed from Java code into native code, we are no longer running inside the JVM and the TCB is marked as not zIIP eligible.
When in native code, CICS can treat the call as if it were from any other supported language. When CICS has completed the requested operation, control once again passes through the JNI and back into Java code within the JVM. This return to the JVM through the JNI will once again mark the TCB as being zIIP eligible.
Offloading Onto a zIIP
Marking a TCB as zIIP eligible doesn’t instantly move the thread of execution from one processor type to another. As we observed earlier, an application may cause the eligibility status of a TCB to be toggled many thousands of times per second. The high-speed processing achieved by modern IBM Z* processors relies heavily on having a constant feed of data available in the lower levels of cache.
Redispatching a TCB from one engine to another forces invalidation of the L1 and L2 caches in one processor and then the reacquisition of the cache data in another processor. Flipping a TCB between a general-purpose and a zIIP engine every time it crossed the JNI would incur significant performance penalties.
Rather than moving the TCB from one engine to another at every JNI crossing, the z/OS OS operates a process known as “lazy switching.” In this configuration a TCB will only be redispatched onto a zIIP engine when the z/OS dispatcher next examines the TCB in the dispatch queue.
The TCB begins life as not zIIP eligible, hence executing on a general-purpose CPU. At some point during its execution, the TCB becomes marked as zIIP eligible. In our case, this would be where control passes into the JVM. Although the TCB is now marked as zIIP eligible, it continues to execute on the same GCP. Eventually, the TCB is suspended and then subsequently reexamined by the z/OS dispatcher. At this time, the TCB is already marked as eligible for offload to a zIIP. The TCB is then dispatched onto the zIIP engine to continue execution: the TCB has been offloaded to a zIIP.
Alternative Execution Paths
During the subsequent execution path, the TCB may become briefly marked as no longer zIIP eligible. For example, the application may have made a call into CICS that didn’t suspend the current TCB. The lazy switching process described earlier doesn’t instantly move the TCB to a GCP, but instead allows execution to continue on a zIIP.
The final scenario to consider is when a zIIP eligible TCB is ready for dispatch, but no zIIP engines are available. In this situation, z/OS can delay execution of zIIP eligible work on the assumption that zIIP capacity will become available shortly. The z/OS dispatcher may also decide that response time is of greater priority than offloading every CPU cycle to a zIIP. In this case, work will resume execution on a GCP, even though it’s eligible for offloading.
The TCB eventually reaches a position where it’s marked as not zIIP eligible, and any subsequent redispatch will result in execution continuing on a GCP.
Ian Burnett is based out of IBM Hursley in the U.K. and is lead of the performance team for the CICS development organization.
Sponsored Content3 Unknown Risks in Your Resiliency Armor
Post a Comment
Note: Comments are moderated and will not appear until approvedcomments powered by Disqus