OPS/MVS: Static Variables usage in OPS/REXX programs - Best Practice.
search cancel

OPS/MVS: Static Variables usage in OPS/REXX programs - Best Practice.

book

Article ID: 28142

calendar_today

Updated On: 09-16-2024

Products

OPS/MVS Event Management & Automation

Issue/Introduction

When writing OPS/REXX programs, there are usually multiple ways of achieving the same objective. However, some coding techniques may have unintended side effects that can seriously impact the overall performance of the code. This article describes how the misuse of Static Variables might create an undesired impact in CPU utilization

 

Environment

OPS/MVS-Event Management & Automation-for JES2

Resolution

Description:

The following two AOF MSG rules perform similar functions:

Example rule 1 )MSG ADASTATICS
)INIT
GLVTEMPM.L1.L2.A = 1
GLVTEMPM.L1.L2.B = 1
GLVTEMPM.L1.L2.C = 1
GLVTEMPM.L1.L2.D = 1
GLVTEMPM.L1.L2.E = 1
GLVTEMPM.L1.L2.F = 1
GLVTEMPM.L1.L2.G = 1
GLVTEMPM.L1.L2.H = 1
GLVTEMPM.L1.L2.I = 1
GLVTEMPM.L1.L2.J = 1
GLVTEMPM.L1.L2.K = 1
GLVTEMPM.L1.L2.L = 1
GLVTEMPM.L1.L2.M = 1
GLVTEMPM.L1.L2.N = 1
GLVTEMPM.L1.L2.O = 1
GLVTEMPM.L1.L2.P = 1
GLVTEMPM.L1.L2.Q = 1
GLVTEMPM.L1.L2.R = 1
GLVTEMPM.L1.L2.S = 1
GLVTEMPM.L1.L2.T = 1
GLVTEMPM.L1.L2.U = 1
GLVTEMPM.L1.L2.V = 1
GLVTEMPM.L1.L2.W = 1
GLVTEMPM.L1.L2.X = 1
GLVTEMPM.L1.L2.Y = 1
GLVTEMPM.L1.L2.Z = 1
)PROC
if GLVTEMPM.L1.L2.A > 0 then
GLVTEMPM.L1.L2.A = GLVTEMPM.L1.L2.A + 1
if GLVTEMPM.L1.L2.B > 0 then
GLVTEMPM.L1.L2.B = GLVTEMPM.L1.L2.B + 1
if GLVTEMPM.L1.L2.C > 0 then



Example rule 2 )MSG ADASTATICS
)INIT
itemp = OPSVALUE('GLVTEMPM.L1.L2.A','U',1)
itemp = OPSVALUE('GLVTEMPM.L1.L2.B','U',1)
itemp = OPSVALUE('GLVTEMPM.L1.L2.C','U',1)
itemp = OPSVALUE('GLVTEMPM.L1.L2.D','U',1)
itemp = OPSVALUE('GLVTEMPM.L1.L2.E','U',1)
itemp = OPSVALUE('GLVTEMPM.L1.L2.F','U',1)
itemp = OPSVALUE('GLVTEMPM.L1.L2.G','U',1)
itemp = OPSVALUE('GLVTEMPM.L1.L2.H','U',1)
itemp = OPSVALUE('GLVTEMPM.L1.L2.I','U',1)
itemp = OPSVALUE('GLVTEMPM.L1.L2.J','U',1)
itemp = OPSVALUE('GLVTEMPM.L1.L2.K','U',1)
itemp = OPSVALUE('GLVTEMPM.L1.L2.L','U',1)
itemp = OPSVALUE('GLVTEMPM.L1.L2.M','U',1)
itemp = OPSVALUE('GLVTEMPM.L1.L2.N','U',1)
itemp = OPSVALUE('GLVTEMPM.L1.L2.O','U',1)
itemp = OPSVALUE('GLVTEMPM.L1.L2.P','U',1)
itemp = OPSVALUE('GLVTEMPM.L1.L2.Q','U',1)
itemp = OPSVALUE('GLVTEMPM.L1.L2.R','U',1)
itemp = OPSVALUE('GLVTEMPM.L1.L2.S','U',1)
itemp = OPSVALUE('GLVTEMPM.L1.L2.T','U',1)
itemp = OPSVALUE('GLVTEMPM.L1.L2.U','U',1)
itemp = OPSVALUE('GLVTEMPM.L1.L2.V','U',1)
itemp = OPSVALUE('GLVTEMPM.L1.L2.W','U',1)
itemp = OPSVALUE('GLVTEMPM.L1.L2.X','U',1)
itemp = OPSVALUE('GLVTEMPM.L1.L2.Y','U',1)
itemp = OPSVALUE('GLVTEMPM.L1.L2.Z','U',1)
)PROC
if OPSVALUE('GLVTEMPM.L1.L2.A','V') > 1 then
temp = OPSVALUE('GLVTEMPM.L1.L2.A','A',1)
if OPSVALUE('GLVTEMPM.L1.L2.B','V') > 1 then
temp = OPSVALUE('GLVTEMPM.L1.L2.B','A',1)
if OPSVALUE('GLVTEMPM.L1.L2.C','V') > 1 then
temp = OPSVALUE('GLVTEMPM.L1.L2.C','A',1)


When looking at the PROC sections of each rule, which are both fairly small, it appears as if there are no significant differences between the two in terms of performance. However, example rule 1 consumes more than twice as many CPU resources as example rule 2 for each event processed in the PROC section. This occurs because the code in the INIT section is connected to the performance of the PROC section. The OPS/REXX statement GLVTEMPM.L1.L2.A = 1 in the INIT section has the unintended side effect of creating three uninitialized simple variables (L1, L2, and A), which, because they are used in the INIT section, are treated as Static Variables.

Now let us take a look at the code in the PROC section of the example rule 1:

if GLVTEMPM.L1.L2.A > 0 then
GLVTEMPM.L1.L2.A = GLVTEMPM.L1.L2.A + 1

The code references each of the Static Variables (as part of the standard OPS/REXX compound variable name resolution), as well as the temporary global variable three times. Since the overhead of evaluating Static Variables is fairly high, this coding style results in significantly higher CPU consumption than the optimal coding in example rule 2, which specifies the temporary global variable names as character strings.

Also, notice that in example rule 2 different temporary variables (itemp and temp) are used to avoid using the Static Variable (itemp) in the PROC section.

Finally, the OPSVALUE ADD function used in example rule 2 not only provides a serialized add function, but it also reduces the number of accesses to the temporary global variables by two thirds, which further reduces the overhead.

While the above examples may be contrived examples used to illustrate a point, we have seen the former technique used in a MSG * rule, and the result was an inefficient rule that consumed significantly more CPU resources than it should have.

 

 

Additional Information

Static and Global Variables are fully documented in the Using Automated Operations Facility AOF Rules section of the OPS/MVS User Guide.