BINARY (COMP or COMP-4)
BINARY data and synonyms COMP and COMP-4 are the two's complement data representation in COBOL.
BINARY data is declared with a PICTURE clause as with internal or external decimal data but the underlying data representation is as a halfword (2 bytes), a fullword (4 bytes) or a doubleword (8 bytes).
The compiler option TRUNC(OPT | STD | BIN) determines if and how the compiler corrects values back to the declared picture clause and how much significant data is present when accessing a data item.
Although the overall general performance considerations for BINARY data and the TRUNC option from V4 and earlier versions still apply in V6, some of the relative performance differences for the various TRUNC suboptions have changed (sometimes dramatically). These changes may impact coding and compiler option choices.
To quantify the relative and absolute performance differences a series of addition operations on binary data items were executed in a loop on a z15® machine. The 4 tests below contain the same type and number of arithmetic operations but have a varying number of digits. All of the operands are signed.
- TEST 1: 8 additions with one each of 1 through 8 digits
- TEST 2: 8 additions each with 9 digits
- TEST 3: 8 additions with one each of 10 through 17 digits
- TEST 4: 8 additions each with 18 digits
The tests were then compiled varying the TRUNC option.
The first experiment specified the TRUNC(STD) compiler option.
TRUNC(STD) instructs the compiler to always correct back to the specified PICTURE clause and allows the compiler to assume that loaded values only have the specified number of PICTURE clause digits.
TRUNC(STD) | V4 versus TEST 1 | V6 versus TEST 1 | V6 versus V4 |
---|---|---|---|
TEST 1: 1-8 digits | 100% | 100% | 16.6% |
TEST 2: 9 digits | 145.9% | 116.9% | 13.3% |
TEST 3: 10-17 digits | 479.1% | 116.4% | 4% |
TEST 4: 18 digits | 768.2% | 100.5% | 2.2% |
- V6 outperforms V4 for all lengths when using TRUNC(STD).
- Although performance slows as the number of digits increases for both V4 and V6 it slows much more gradually and to much lower overall amount using V6 compared to V4.
The second experiment specified the TRUNC(BIN) compiler option. Specifying this option is equivalent to using the COMP-5 type for all BINARY data.
TRUNC(BIN) instructs the compiler to allow values to only correct back to the underlying data representation (two, four or eight bytes) instead of back to the specified PICTURE clause. This option also requires the compiler to assume that loaded values can have up to two, four or eight bytes worth of significant data.
TRUNC(BIN) | V4 versus TEST 1 | V6 versus TEST 1 | V6 versus V4 |
---|---|---|---|
TEST 1: 1-8 digits | 100% | 100% | 62.5% |
TEST 2: 9 digits | 154.5% | 100.4% | 40.6% |
TEST 3: 10-17 digits | 5098.2% | 1925.5% | 23.6% |
TEST 4: 18 digits | 5099.2% | 1928% | 23.6% |
- V6 also outperforms V4 for all lengths when using TRUNC(BIN).
- V6 shows no slow down when testing at 9 digits.
- There is a dramatic reduction in performance for both V4 and V6 (but more so for V4 in absolute terms) when the length is increased beyond 9 digits. This is due to the TRUNC(BIN) requirement that input data may contain up to the full integer half/full/double word of data (and extra data type conversions and library routines are required).
- Correcting back to the PICTURE clause as with TRUNC(STD) or
- Only correcting back to the two, four or eight byte boundary as with TRUNC(BIN)
TRUNC(OPT) | V4 versus TEST 1 | V6 versus TEST 1 | V6 versus V4 |
---|---|---|---|
TEST 1: 1-8 digits | 100% | 100% | 97% |
TEST 2: 9 digits | 333.3% | 69.7% | 20.4% |
TEST 3: 10-17 digits | 209.7% | 70.4% | 32.7% |
TEST 4: 18 digits | 5553.4% | 129.7% | 2.3% |
- V6 also outperforms V4 when using TRUNC(OPT).
- V6 shows no slow down until the 18 digit case but still vastly outperforms V4 at this longest length.
- The use of 64-bit ‘G’ form instructions enables much more efficient code for > 8 digit cases
- More efficient library routines for the very large TRUNC(BIN) cases
Prioritizing your application for migration to V6 has a specific example of binary double word arithmetic (Large Binary Arithmetic) that demonstrates the performance improvement for this type of operation relative to version 4 of the compiler. In this example V6 is considerably faster than V4 and earlier compiler releases.
The relative performance differences across the different TRUNC options have been smoothed out compared to V4. This is primarily due to the compiler inserting a runtime test for overflow. If no overflow is possible then an expensive ‘divide’ hardware instruction is avoided.
If your data is known to conform to the PICTURE clause then TRUNC(OPT) remains the best overall option to choose but relatively speaking it improves less over TRUNC(STD) than in V4 and overall absolute performance is better with either option in V6.
Although TRUNC(BIN) enables more efficient code when storing out a COMPUTE or MOVE result it continues to significantly harm the performance when these data items are used as input to arithmetic statements (as the compiler must assume the max 2,4,8 byte size). V6 optimizes the correction code for TRUNC(STD) so the performance benefit of TRUNC(BIN) has been reduced slightly.
It might be better to only specify COMP-5 for select data items versus using TRUNC(BIN). For example, performance will usually be improved if data items in COMPUTE statements in particular are not specified with COMP-5.