Monday, July 27, 2026

𝗦𝗰𝗮𝗻𝗻𝗶𝗻𝗴 𝗮 𝟰𝟬 𝗞𝗕 𝗗𝗮𝘁𝗮 𝗔𝗿𝗲𝗮 𝗳𝗼𝗿 𝗟𝗼𝘄𝗲𝗿𝗰𝗮𝘀𝗲 𝗖𝗵𝗮𝗿𝗮𝗰𝘁𝗲𝗿𝘀: 𝗔 𝟱𝟬-𝗠𝗜𝗣𝗦 𝗢𝗽𝘁𝗶𝗺𝗶𝘇𝗮𝘁𝗶𝗼𝗻 𝗦𝘁𝗼𝗿𝘆

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.