How to time COBOL code blocks, prompted by John McKown's "how to: convince programmer something else is better.":
See here:
http://ibmmainframes.com/viewtopic.php?p=294906
The main reason for including the link is to show the program nicely formatted. Here's the post, in case the link-to information ever disappears:
With the usual provisos (don't use in production, don't rely on it being available after z/OS upgrade) here is a module which will make the CPU time available in the program which calls it (or wherever the storage happens to be defined).
At the "front" of a program,
CALL "BBPFTC1" USING ADDRESS OF a-doubleword-binary-defined-in-linkage
Then forget about the sub-program, no longer needed. You could, I suppose, even CANCEL it if you've loaded it dynamically.
When you need the CPU time, just use the field from Linkage. Typically, save it before a suspect block of code. Save it somewhere else after the block. Compare. To get the time "big enough", "divide by 4096" to get it to miliseconds.
ID DIVISION.
PROGRAM-ID. BBPFTC1.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 W-PSA-POINTER POINTER.
LINKAGE SECTION.
01 PSA-CONTROL-BLOCK.
05 FILLER PIC X(548).
05 PSA-CB-ASCB-POINTER POINTER.
01 ASCB-CONTROL-BLOCK.
05 FILLER PIC X(64).
05 ASCB-CB-CPUTIME PIC X(8).
01 L-CPU-TIME-PTR USAGE POINTER.
PROCEDURE DIVISION USING L-CPU-TIME-PTR.
SET W-PSA-POINTER TO NULL
SET ADDRESS OF PSA-CONTROL-BLOCK
TO W-PSA-POINTER
SET ADDRESS OF ASCB-CONTROL-BLOCK
TO PSA-CB-ASCB-POINTER
SET L-CPU-TIME-PTR TO ADDRESS OF ASCB-CB-CPUTIME
GOBACK
.
----------------------------
Here's an example of how to use it, prepared for Peter Hunkeler's topic on the "decimal overflow", "How to Identify modules as C/C++ or Cobol, or ASM from dump (SYSMDUMP)." Unfortunately without formatting:
IDENTIFICATION DIVISION.
PROGRAM-ID. 'STAB64'.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 W-WHEN-COMPILED PIC X(4)/XX/XXBXXBXXBXX.
01 W-LARGE-SOURCE-FIELD PIC 9.
01 W-LARGE-TARGET-FIELD PIC 9.
01 W-LARGE-ANSWER PIC 9.
01 W-SMALL-SOURCE-FIELD PIC 9.
01 W-SMALL-TARGET-FIELD PIC 9.
01 W-SMALL-ANSWER PIC 9.
01 W-NUMBER-OF-LOOPS BINARY PIC 9(8).
01 W-ZONED-TO-BIN PIC 9(8).
01 CALC-ITERATION-LENGTH BINARY PIC 9(1).
01 W-EMPTY-CPU COMP-5 PIC 9(18).
01 W-GROSS-CPU COMP-5 PIC 9(18).
01 W-NETT-CPU COMP-5 PIC 9(18).
01 W-ORIG-CPU COMP-5 PIC 9(18).
01 W-CPU-TIME-FOR-DISPLAY PIC Z(11)9,99,9999.
01 W-CPU-BEFORE-BLK1 COMP-5 PIC 9(18).
01 W-CPU-BEFORE-BLK1X
REDEFINES W-CPU-BEFORE-BLK1.
05 FILLER PIC X(8).
01 W-CPU-AFTER-BLK1 COMP-5 PIC 9(18).
01 W-CPU-AFTER-BLK1X
REDEFINES W-CPU-AFTER-BLK1.
05 FILLER PIC X(8).
01 W-CPU-BEFORE-BLK2 COMP-5 PIC 9(18).
01 W-CPU-BEFORE-BLK2X
REDEFINES W-CPU-BEFORE-BLK2.
05 FILLER PIC X(8).
01 W-CPU-AFTER-BLK2 COMP-5 PIC 9(18).
01 W-CPU-AFTER-BLK2X
REDEFINES W-CPU-AFTER-BLK2.
05 FILLER PIC X(8).
01 W-CEE3SPM-FUNCTION BINARY PIC 9(8).
88 W-CEE3SPM-QUERY VALUE 2.
88 W-CEE3SPM-SET VALUE 1.
01 W-CEE3SPM-FUNCTION-VALUES PIC X(80).
01 W-CEE3SPM-FB-IGNORED-HERE PIC X(12).
LINKAGE SECTION.
01 PARM-DATA.
05 PARM-LENGTH COMP PIC 9(4).
05 PARM-VALUE.
10 FILLER OCCURS 0 TO 100 TIMES
DEPENDING ON PARM-LENGTH.
15 FILLER PIC X.
01 PARM-WITH-CONTEXT.
05 PARM-IND PIC X.
88 SET-OVERFLOW-OFF VALUE "1".
05 PARM-NUMBER-OF-ITERATIONS.
10 FILLER OCCURS 0 TO 8 TIMES
DEPENDING ON CALC-ITERATION-LENGTH.
15 FILLER PIC X.
01 L-CPU-TIME PIC X(8).
PROCEDURE DIVISION USING
PARM-DATA
.
PERFORM INITIAL-PROCESSING
PERFORM DO-THE-SMALL-ADD
PERFORM DO-THE-LARGE-ADD
PERFORM FINAL-PROCESSING
GOBACK
.
INITIAL-PROCESSING.
PERFORM SAY-WHO-WE-ARE
PERFORM PROCESS-PARM-FOR-LOOP-COUNT
PERFORM QUERY-AND-DISPLAY-MASK
IF SET-OVERFLOW-OFF
PERFORM SET-DECIMAL-IN-MASK-OFF
END-IF
PERFORM SAVE-CPU-START-TIME
.
SAY-WHO-WE-ARE.
MOVE FUNCTION WHEN-COMPILED TO W-WHEN-COMPILED
DISPLAY
"STAB64 COMPILED ON: "
W-WHEN-COMPILED
.
PROCESS-PARM-FOR-LOOP-COUNT.
PERFORM REDEFINES-TO-ALLOW-ODO
SUBTRACT LENGTH OF PARM-IND FROM PARM-LENGTH
GIVING CALC-ITERATION-LENGTH
MOVE PARM-NUMBER-OF-ITERATIONS
TO W-ZONED-TO-BIN
MOVE W-ZONED-TO-BIN TO W-NUMBER-OF-LOOPS
DISPLAY
">"
PARM-NUMBER-OF-ITERATIONS
"<"
.
REDEFINES-TO-ALLOW-ODO.
SET ADDRESS OF PARM-WITH-CONTEXT
TO ADDRESS OF
PARM-VALUE
.
QUERY-AND-DISPLAY-MASK.
SET W-CEE3SPM-QUERY TO TRUE
CALL 'CEE3SPM' USING W-CEE3SPM-FUNCTION
W-CEE3SPM-FUNCTION-VALUES
W-CEE3SPM-FB-IGNORED-HERE
DISPLAY
W-CEE3SPM-FUNCTION-VALUES
.
SET-DECIMAL-IN-MASK-OFF.
SET W-CEE3SPM-SET TO TRUE
MOVE 'NOF NOD NOU NOS' TO W-CEE3SPM-FUNCTION-VALUES
CALL 'CEE3SPM' USING
W-CEE3SPM-FUNCTION
W-CEE3SPM-FUNCTION-VALUES
W-CEE3SPM-FB-IGNORED-HERE
.
SAVE-CPU-START-TIME.
CALL "BBPFTC1" USING
ADDRESS OF
L-CPU-TIME
.
DO-THE-SMALL-ADD.
ACCEPT W-SMALL-SOURCE-FIELD
ACCEPT W-SMALL-TARGET-FIELD
MOVE L-CPU-TIME TO W-CPU-BEFORE-BLK1X
PERFORM
W-NUMBER-OF-LOOPS TIMES
ADD W-SMALL-SOURCE-FIELD TO W-SMALL-TARGET-FIELD
GIVING W-SMALL-ANSWER
END-PERFORM
MOVE L-CPU-TIME TO W-CPU-AFTER-BLK1X
DISPLAY "THE ADD SEEMED TO WORK"
DISPLAY W-SMALL-ANSWER
.
DO-THE-LARGE-ADD.
ACCEPT W-LARGE-SOURCE-FIELD
ACCEPT W-LARGE-TARGET-FIELD
MOVE L-CPU-TIME TO W-CPU-BEFORE-BLK2X
PERFORM W-NUMBER-OF-LOOPS TIMES
ADD W-LARGE-SOURCE-FIELD TO W-LARGE-TARGET-FIELD
GIVING W-LARGE-ANSWER
END-PERFORM
MOVE L-CPU-TIME TO W-CPU-AFTER-BLK2X
DISPLAY "THE LARGE ADD SEEMED TO WORK"
DISPLAY W-LARGE-ANSWER
.
FINAL-PROCESSING.
PERFORM SHOW-CPU-USED-BLOCK-1
PERFORM SHOW-CPU-USED-BLOCK-2
.
SHOW-CPU-USED-BLOCK-1.
COMPUTE W-GROSS-CPU = ( W-CPU-AFTER-BLK1
- W-CPU-BEFORE-BLK1 )
/ 4096
MOVE W-GROSS-CPU TO W-CPU-TIME-FOR-DISPLAY
DISPLAY
"CODE BLOCK 1 GROSS CPU"
">"
W-CPU-TIME-FOR-DISPLAY
"<"
.
SHOW-CPU-USED-BLOCK-2.
COMPUTE W-GROSS-CPU = ( W-CPU-AFTER-BLK2
- W-CPU-BEFORE-BLK2 )
/ 4096
MOVE W-GROSS-CPU TO W-CPU-TIME-FOR-DISPLAY
DISPLAY
"CODE BLOCK 2 GROSS CPU"
">"
W-CPU-TIME-FOR-DISPLAY
"<"
.
JCL to run it:
//RUNIT EXEC PGM=STAB64,TIME=(,reasonableforyoursystem),PARM='G1'
//STEPLIB DD DISP=SHR,DSN=yourload
// DD DISP=SHR,DSN=yourLEruntime IBM-provided is CEE.SCEELKED, I think
//SYSOUT DD SYSOUT=*
//CEEOPTS DD *
TRAP(OFF)
RPTOPTS(ON)
//SYSIN DD *
1
1
9
9
To get the overflow bit "on", use compiler option PGMNAME(LONGUPPER) or LONGMIXED.
See the CPU counts with TRAP(OFF), see the S0CA with TRAP(ON). Then change the G in the PARM to F (all values other than F are equal) to get the program to turn the overflow bit "off", and compare and contrast.
This program demonstrates the point made by Tom Ross in a presentation, which was referred to in Peter Hunkeler's topic.
1 and 1, and 9 and 9, are the two one-digit values which will be added together giving a one-digit result. 1 + 1 will not cause overflow, 9 + 9 (or indeed 9 + anything other than zero) will cause overflow.
In the example (and in Tom Ross's) the hit is huge, but hopefully even when overflow occurs, it is not the regular result, although people have been affected by this.
----------------------------------------------------------------------
For IBM-MAIN subscribe / signoff / archive access instructions,
send email to
list...@listserv.ua.edu with the message: INFO IBM-MAIN