A CICS transaction was executing across approximately 150 CICS regions. As part of the transaction flow, a COBOL program contained the code shown below to check for the presence of lowercase alphabetic characters within a 40 KB data area. This code was consuming about 50 MIPS during peak CPU utilization.
MOVE 'N' TO WS-LC-FOUND
PERFORM VARYING WS-SUB1 FROM 1 BY 1
UNTIL WS-SUB1 > LENGTH OF WS-DATA
OR WS-LC-FOUND = 'Y'
IF WS-DATA (WS-SUB1:1) = 'a' OR 'b' OR 'c' OR 'd' OR
'e' OR 'f' OR 'g' OR 'h' OR
'i' OR 'j' OR 'k' OR 'l' OR
'm' OR 'n' OR 'o' OR 'p' OR
'q' OR 'r' OR 's' OR 't' OR
'u' OR 'v' OR 'w' OR 'x' OR
'y' OR'z'
MOVE 'Y' TO WS-LC-FOUND
END-IF
END-PEFORM
Initial Optimization Approach
To address the CPU overhead, I developed an assembler-based alternative that used the TRT instruction to perform the lowercase character check far more efficiently than the original COBOL implementation. While the approach achieved significant performance improvements, the customer declined to implement it because assembler code was considered difficult to maintain and support.
Revised Solution
To address the customer's maintainability concerns, I developed an alternative solution using standard COBOL code, shown below. The COBOL compiler internally generated code that leveraged the assembler TRT (Translate and Test) instruction to scan for lowercase characters efficiently. The customer accepted this approach because it avoided the need to maintain assembler source code while still delivering the desired performance benefits. After implementation in production, the solution reduced CPU consumption by approximately 50 MIPS.
In the EBCDIC character set, the hexadecimal values for lowercase alphabetic characters are:
• 'a' through 'i': X'81' through X'89'
• 'j' through 'r': X'91' through X'99'
• 's' through 'z': X'A2' through X'A9'
These three contiguous ranges represent all lowercase letters from a to z.
This solution involved defining a custom data type, VALID-DATA, containing every possible byte value except lowercase alphabetic characters (a through z). A PERFORM loop then scanned the data area in 256-byte chunks, verifying that each segment contained only characters defined in VALID-DATA. This coding approach enabled the COBOL compiler to make use of assembler TRT instruction.
IDENTIFICATION DIVISION.
PROGRAM-ID. TESTGPM.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
SPECIAL-NAMES.
CLASS VALID-DATA IS X'00' THRU X'80',
X'8A' THRU X'90',
X'9A' THRU X'A1',
X'AA' THRU X'FF'.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-DATA PIC X(40000).
01 WS-SUB1 PIC S9(8) COMP.
01 WS-SUB2 PIC S9(8) COMP.
01 WS-QUO PIC S9(8) COMP.
01 WS-REM PIC S9(8) COMP.
01 WS-LC-FOUND PIC X(01).
PROCEDURE DIVISION.
MOVE 'N' TO WS-LC-FOUND
DIVIDE LENGTH OF WS-DATA BY 256 GIVING WS-QUO
REMAINDER WS-REM
MOVE 1 TO WS-SUB2
PERFORM VARYING WS-SUB1 FROM 1 BY 1
UNTIL WS-SUB1 > WS-QUO
OR WS-LC-FOUND = 'Y'
IF WS-DATA (WS-SUB2:256) IS VALID-DATA
CONTINUE
ELSE
MOVE 'Y' TO WS-LC-FOUND
END-IF
ADD 256 TO WS-SUB2
END-PERFORM
IF WS-DATA (WS-SUB2:WS-REM) IS VALID-DATA
CONTINUE
ELSE
MOVE 'Y' TO WS-LC-FOUND
END-IF
GOBACK.
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.