Strategies and techniques to optimize JCL for maximum efficiency and throughput
Performance optimization is a critical aspect of JCL development, especially in enterprise environments where jobs process large volumes of data and operate under tight processing windows. Well-optimized JCL can significantly reduce resource consumption, improve throughput, and decrease costs.
Optimized JCL minimizes CPU, memory, and I/O usage, reducing costs and allowing more work to be processed with existing hardware.
Faster job completion enables tighter batch windows, improved data currency, and better service level agreement (SLA) compliance.
Efficient jobs allow the system to process more work concurrently, maximizing the value of your mainframe investment.
Well-designed jobs are less likely to fail due to resource constraints, ensuring more consistent operations.
Performance tuning involves optimizing several key areas:
Performance optimization should be based on measurement rather than assumptions. Always establish baseline metrics before making changes and measure the impact of your optimizations.
Dataset access is often the primary performance bottleneck in JCL jobs. Optimizing how data is stored, accessed, and processed can yield significant performance improvements.
Block size has a direct impact on I/O efficiency. Larger block sizes generally reduce the number of I/O operations required to process a dataset.
1234//OUTDD DD DSN=MY.OUTPUT.DATASET, // DISP=(NEW,CATLG,DELETE), // SPACE=(CYL,(10,5),RLSE), // DCB=(RECFM=FB,LRECL=80,BLKSIZE=27920)
Increasing the number of buffers can dramatically improve I/O performance by reducing physical I/O operations.
123456//INDD DD DSN=MY.LARGE.INPUT.FILE,DISP=SHR, // DCB=(BUFNO=20) // For VSAM files: //VSAMDD DD DSN=MY.VSAM.DATASET,DISP=SHR, // AMP=('BUFND=20,BUFNI=5')
Buffer optimization guidelines:
Important: Increasing buffer counts allocates more memory. Monitor for increased REGION usage when adjusting buffer parameters.
Optimize temporary datasets to minimize I/O and disk space usage:
1234567891011121314// Passing datasets between steps //STEP1 EXEC PGM=PROGRAM1 //OUTFILE DD DSN=&&TEMP, // DISP=(NEW,PASS,DELETE), // SPACE=(CYL,(10,5),RLSE) //... //STEP2 EXEC PGM=PROGRAM2 //INFILE DD DSN=&&TEMP,DISP=(OLD,DELETE) // Using VIO for small temporary datasets //TEMPDD DD DSN=&&SMALLTEMP, // DISP=(NEW,DELETE), // UNIT=VIO, // SPACE=(TRK,(5,1))
In SMS-managed environments, storage classes can be used to direct datasets to appropriate storage tiers based on performance requirements:
1234//PERFDD DD DSN=CRITICAL.PERFORMANCE.DATASET, // DISP=(NEW,CATLG,DELETE), // STORCLAS=PERFCLAS, // SPACE=(CYL,(100,50),RLSE)
Work with your storage administrator to understand available storage classes and their characteristics. Some environments may offer:
Input/Output operations are typically the most time-consuming aspect of batch processing. Strategic I/O optimization can dramatically improve job performance.
Sequential access is almost always more efficient than random access. Structure your processing to favor sequential operations:
Data compression reduces storage requirements and I/O volume, improving performance for I/O-bound jobs:
12345//COMPDD DD DSN=MY.COMPRESSED.DATASET, // DISP=(NEW,CATLG,DELETE), // SPACE=(CYL,(50,10),RLSE), // DCB=(RECFM=FB,LRECL=80,BLKSIZE=27920), // DATACLAS=COMPRESS
Consider different compression approaches:
Note: Compression trades CPU usage for reduced I/O. For CPU-bound workloads, carefully evaluate if the I/O savings justify the additional processing.
Avoid unnecessary dataset copies between job steps:
123456789//STEP1 EXEC PGM=PROG1 //OUTDD DD DSN=TEMP.FILE1,DISP=(,CATLG) //... //STEP2 EXEC PGM=PROG2 //INDD DD DSN=TEMP.FILE1,DISP=SHR //OUTDD DD DSN=TEMP.FILE2,DISP=(,CATLG) //... //STEP3 EXEC PGM=PROG3 //INDD DD DSN=TEMP.FILE2,DISP=SHR
123456789//STEP1 EXEC PGM=PROG1 //OUTDD DD DSN=&&TEMP1,DISP=(,PASS) //... //STEP2 EXEC PGM=PROG2 //INDD DD DSN=&&TEMP1,DISP=(OLD,DELETE) //OUTDD DD DSN=&&TEMP2,DISP=(,PASS) //... //STEP3 EXEC PGM=PROG3 //INDD DD DSN=&&TEMP2,DISP=(OLD,DELETE)
Additional techniques for minimizing copies:
Common utilities have specialized parameters for I/O performance:
1234567//SORT EXEC PGM=SORT //SORTIN DD DSN=UNSORTED.FILE,DISP=SHR //SORTOUT DD DSN=SORTED.FILE,DISP=(NEW,CATLG,DELETE) //SYSIN DD * SORT FIELDS=(1,10,CH,A) OPTION EQUALS,FILSZ=E50000000 /*
Key utility optimization techniques:
Efficient memory allocation and usage are crucial for job performance. Too little memory can cause abends, while excessive allocation wastes system resources.
The REGION parameter controls memory allocation for a job or step:
12345//MYJOB JOB (ACCT),'MY JOB',CLASS=A,REGION=0M // Step-specific REGION allocation //BIGSTEP EXEC PGM=BIGJOB,REGION=256M //SMALLSTEP EXEC PGM=SMALLJOB,REGION=64M
For applications that use memory above the 2GB bar, consider MEMLIMIT:
12345//BIGJOB JOB (ACCT),'MEMORY INTENSIVE', // CLASS=A,REGION=0M,MEMLIMIT=4G // Step-specific MEMLIMIT //BIGSTEP EXEC PGM=LARGEMEM,MEMLIMIT=8G
MEMLIMIT guidelines:
Advanced memory optimization may involve influencing virtual storage layout:
12//STEP1 EXEC PGM=MYPROG, // PARM='STACK(128K,128K,ANYWHERE),HEAP(4M,1M,ANYWHERE)'
Monitor job memory usage over time. Application behavior may change with data volume growth or code changes, requiring periodic reassessment of memory allocations.
VIO can dramatically improve performance for small temporary datasets by keeping them in memory:
1234//SORTWORK DD DSN=&&TEMP, // UNIT=VIO, // SPACE=(CYL,(5,1)), // DCB=(RECFM=FB,LRECL=80,BLKSIZE=27920)
VIO best practices:
Parallel execution can dramatically reduce elapsed time for complex workloads. Modern mainframe environments offer several approaches to parallelism in JCL.
Breaking a large sequential process into multiple independent jobs allows concurrent execution:
12345//BIGJOB JOB (ACCT),'PROCESS ALL',CLASS=A //STEP1 EXEC PGM=PROCESS //INDD DD DSN=HUGE.INPUT.FILE,DISP=SHR //OUTDD DD DSN=HUGE.OUTPUT.FILE, // DISP=(NEW,CATLG,DELETE)
123456789101112131415161718192021222324//CTRL JOB (ACCT),'CONTROL JOB',CLASS=A //SPLIT EXEC PGM=FILESPLIT //IN DD DSN=HUGE.INPUT.FILE,DISP=SHR //OUT1 DD DSN=TEMP.PART1,DISP=(,CATLG) //OUT2 DD DSN=TEMP.PART2,DISP=(,CATLG) //OUT3 DD DSN=TEMP.PART3,DISP=(,CATLG) //... //SUBMIT EXEC PGM=IEBGENER //SYSUT1 DD * // PART1 JOB (ACCT),'PROCESS P1',CLASS=A //STEP1 EXEC PGM=PROCESS //INDD DD DSN=TEMP.PART1,DISP=SHR //OUTDD DD DSN=TEMP.OUT1,DISP=(,CATLG) /* //SYSUT2 DD SYSOUT=(A,INTRDR) //... // (Similar SUBMIT steps for PART2, PART3) //... //COMBINE EXEC PGM=APPEND,COND=(0,LT) //IN1 DD DSN=TEMP.OUT1,DISP=SHR //IN2 DD DSN=TEMP.OUT2,DISP=SHR //IN3 DD DSN=TEMP.OUT3,DISP=SHR //OUT DD DSN=HUGE.OUTPUT.FILE, // DISP=(NEW,CATLG,DELETE)
Considerations for job-level parallelism:
Some JES environments support parallel execution of job steps:
1234567891011121314//MYJOB JOB (ACCT),'PARALLEL STEPS',CLASS=A //* //JCLLIB JCLLIB ORDER=SYS1.PROCLIB //* //JOBSET JOBPARM CARDS=YES //* //STEP1A EXEC PGM=PROGRAM1 //... //STEP1B EXEC PGM=PROGRAM2 //* These steps can run in parallel //... //STEP2 EXEC PGM=FINALIZE // IF (STEP1A.RC<=4 & STEP1B.RC<=4) THEN //...
Note: The JOBPARM CARDS=YES option is JES2-specific. Different mainframe environments may have different mechanisms for parallel step execution.
Many mainframe utilities and applications support internal parallelism:
1234567891011121314151617//SORT EXEC PGM=SORT //SORTIN DD DSN=HUGE.INPUT.FILE,DISP=SHR //SORTOUT DD DSN=HUGE.OUTPUT.FILE, // DISP=(NEW,CATLG,DELETE) //SYSIN DD * SORT FIELDS=(1,10,CH,A) OPTION EQUALS,DYNALLOC=(SYSDA,8),PARALLEL /* //DB2UTIL EXEC PGM=DSNUTILB,PARM='DB2P,TESTUTIL' //SYSPRINT DD SYSOUT=* //SYSIN DD * RUNSTATS TABLESPACE DB1.TS1 INDEX ALL SHRLEVEL REFERENCE PARALLELISM 4 /*
Common programs with parallel capabilities:
Workload Manager can be leveraged for improved parallel execution:
Parallelism introduces complexity in debugging and recovery. Always include robust error handling and ensure you can process partial results in case of failures.
Effective measurement is the foundation of all performance optimization. Without measurement, you can't determine if your changes are helping or hurting.
System Management Facilities (SMF) records provide detailed performance metrics:
SMF records can be analyzed using tools like IBM's MICS, SAS, or custom reporting applications. These tools help extract and compare job performance metrics over time.
Job logs contain valuable performance information that can be analyzed without specialized tools:
123456IEF285I JOB12345 ENDED. NAME-MYJOB TOTAL CPU TIME= 1.083 TOTAL ELAPSED TIME= 15.133 IEF03361 STEP /PROCSTEP /STEP TOTCPU TOTHU VIRT ALLOC BYTES STEP01 / / 0.717 0.717 2048K 500K 12M STEP02 / / 0.366 0.366 4096K 1000K 24M
Key metrics to monitor in job logs:
Several tools can help analyze and optimize JCL performance:
Provides system-wide performance measurements including CPU, I/O, and memory usage patterns.
Allows viewing and analysis of job output including resource usage metrics.
Products like IBM Tivoli, BMC MAINVIEW, and CA SYSVIEW provide comprehensive performance monitoring.
Organizations often develop tailored reporting solutions for specific performance metrics.
Establish a methodical approach to performance measurement:
For accurate performance comparisons, ensure measurements are taken under similar system load conditions. Measure at both peak and off-peak times to understand performance variability.
Practice your JCL performance optimization skills with these exercises:
Review and optimize the following JCL for better I/O performance:
12345678910111213141516171819202122//PERFORM JOB (ACCT#),'PERFORMANCE TEST',CLASS=A, // MSGCLASS=X,NOTIFY=&SYSUID //* //STEP01 EXEC PGM=IEBGENER //SYSUT1 DD DSN=LARGE.INPUT.FILE,DISP=SHR //SYSUT2 DD DSN=LARGE.OUTPUT.FILE, // DISP=(NEW,CATLG,DELETE), // SPACE=(TRK,(1000,100)), // DCB=(RECFM=FB,LRECL=80,BLKSIZE=800) //SYSPRINT DD SYSOUT=* //SYSIN DD DUMMY //* //STEP02 EXEC PGM=SORT //SORTIN DD DSN=LARGE.OUTPUT.FILE,DISP=SHR //SORTOUT DD DSN=LARGE.SORTED.FILE, // DISP=(NEW,CATLG,DELETE), // SPACE=(TRK,(1000,100)), // DCB=(RECFM=FB,LRECL=80,BLKSIZE=800) //SYSOUT DD SYSOUT=* //SYSIN DD * SORT FIELDS=(1,10,CH,A) /*
Task: Improve this JCL by:
Explain the rationale behind each optimization you make.
Analyze this memory-intensive JCL and suggest improvements:
1234567891011121314151617//BIGMEM JOB (ACCT#),'MEMORY TEST',CLASS=A, // MSGCLASS=X,NOTIFY=&SYSUID,REGION=4M //* //STEP01 EXEC PGM=MEMORYHOG //INPUT DD DSN=HUGE.INPUT.FILE,DISP=SHR //OUTPUT DD SYSOUT=* //SYSPRINT DD SYSOUT=* //* //STEP02 EXEC PGM=DATAPROC,REGION=6M //IN DD DSN=HUGE.INPUT.FILE,DISP=SHR //OUT DD DSN=HUGE.OUTPUT.FILE, // DISP=(NEW,CATLG,DELETE), // SPACE=(CYL,(100,10)) //TEMP DD DSN=&&TEMPFILE, // DISP=(NEW,DELETE), // SPACE=(CYL,(50,5)) //SYSPRINT DD SYSOUT=*
Task: Optimize the memory usage by:
Consider both 31-bit and 64-bit addressing options.
Design a parallel processing solution for this sequential job:
12345678910111213141516171819//SEQJOB JOB (ACCT#),'SEQUENTIAL JOB',CLASS=A //* //STEP01 EXEC PGM=EXTRACT //IN DD DSN=REGION.MASTER.FILE,DISP=SHR //OUT DD DSN=EXTRACTED.DATA, // DISP=(NEW,CATLG,DELETE), // SPACE=(CYL,(200,20)) //* //STEP02 EXEC PGM=TRANSFORM,COND=(0,LT,STEP01) //IN DD DSN=EXTRACTED.DATA,DISP=SHR //OUT DD DSN=TRANSFORMED.DATA, // DISP=(NEW,CATLG,DELETE), // SPACE=(CYL,(250,25)) //* //STEP03 EXEC PGM=ANALYZE,COND=(0,LT,STEP02) //IN DD DSN=TRANSFORMED.DATA,DISP=SHR //REPORT DD DSN=FINAL.REPORT, // DISP=(NEW,CATLG,DELETE), // SPACE=(CYL,(10,5))
Task: Redesign this job to:
Draw a diagram of your parallel execution strategy and explain how it improves performance.
JCL performance optimization is a critical skill for mainframe professionals that can yield significant business benefits through reduced resource usage, faster processing, and improved throughput.
In this tutorial, we covered:
Remember that performance optimization should always follow these principles:
Performance optimization is an ongoing process. Regularly review and tune your critical JCL as data volumes grow, processing requirements change, and system environments evolve.
1. Which JCL parameter helps optimize memory usage for a job step?
2. What is the most efficient disposition for temporary datasets that are only needed within a job?
3. Which of these techniques can improve I/O performance in JCL?
4. What is the primary benefit of specifying BUFNO in your JCL?
5. Which technique allows multiple steps to execute simultaneously within a job?