COMPUTE

A significant number of COMPUTE, ADD, SUBTRACT, MULTIPLY, DIVIDE statements show improved performance in V6.

Under "Data types" in the following examples, italics are used to indicate the variant tested for performance, but all data types listed would demonstrate similar performance results.

Larger decimal multiply/divide

Statement: COMPUTE (* | /), MULTIPLY, DIVIDE

Data types: COMP-3, DISPLAY, NATIONAL

Options: OPT(1 | 2)

Conditions: When intermediate results exceed the limits for using the hardware packed decimal instructions. This occurs at around 15 digits depending on the particular operation.

V4 behavior: Call to runtime routine

V6 behavior: Inline after converting to DFP

Source Example:
1 z14v2 pic s9(14)v9(2)
1 z13v2 pic s9(13)v9(2)

Compute z14v2 = z14v2 / z13v2.

Performance: V6 is 43% faster than V4

Zoned decimal (DISPLAY) arithmetic

Statement: COMPUTE (+ | - | * | /), ADD, SUBTRACT, MULTIPLY, DIVIDE

Data types: DISPLAY

Options: OPT(1 | 2), ARCH(10)

Conditions: In all cases

V4 behavior: Inline using packed decimal instructions

V6 behavior: Inline after converting to DFP

Source Example:
1 z12v2 pic s9(12)v9(2)
1 z11v2 pic s9(11)v9(2)
Compute z12v2 = z12v2 / z11v2

Performance: V6 is 59% faster than V4

Divide by powers of ten (10,100,1000,..)

Statement: COMPUTE (/), DIVIDE

Data types: COMP-3, DISPLAY, NATIONAL

Options: Default

Conditions: Divisor is a power of 10 (e.g. 10,100,1000,…)

V4 behavior: Use packed decimal divide (DP) instruction

V6 behavior: Model as decimal right shift

Source Example:
1 p8v2a pic s9(8)v9(2) comp-3
1 p8v2b pic s9(8)v9(2) comp-3

Compute p8v2b = p8v2a / 100

Performance: V6 is 45% faster than V4

Multiply by powers of ten (10,100,1000,..)

Statement: COMPUTE (/), MULTIPLY

Data types: COMP-3, DISPLAY, NATIONAL

Options: Default

Conditions: Multiply is a power of 10 (e.g. 10,100,1000,…)

V4 behavior: Use packed decimal multiply (MP) instruction

V6 behavior: Model as decimal left shift

Source Example:
1 z5v2 pic s9(5)v9(2)
1 z7v2 pic s9(7)v9(2)

Compute z7v2 = z5v2 * 100

Performance: V6 is 73% faster than V4

Decimal exponentiation

Statement: COMPUTE (**)

Data types: COMP-3, DISPLAY, NATIONAL

Options: Default

Conditions: In all cases

V4 behavior: Call to runtime routine

V6 behavior: Call to a more efficient runtime routine

Source Example:
1  R     PIC  9v9(8) value 0.05.
1  NF    PIC  9(4) value 300.
1  EXP   PIC  9(23)v9(8).

COMPUTE EXP = (1.0 + R) ** NF.

Performance: V6 is 96% faster than V4

Decimal scaling and divide

Statement: COMPUTE (/), DIVIDE

Data types: COMP-3, DISPLAY, NATIONAL

Options: Default

Conditions: When the divisor value and the decimal scaling cancel out. In the example below, the divide operation necessitates a decimal left shift by 2, and since the divide by 100 is modelled as the decimal right shift by 2, these operations cancel out.

V4 behavior: Use packed decimal shift (SRP) and divide (DP) instructions

V6 behavior: Divide and decimal scaling are cancelled out so instructions equivalent to a simple MOVE operation are generated

Source Example:
1 p9v0 pic s9(9) comp-3
1 p10v2 pic s9(10)v9(2) comp-3.

COMPUTE p10v2 = p9v0 / 100

Performance: V6 is 89% faster than V4

TRUNC(STD) binary arithmetic

Statement: COMPUTE (+ | - | * | /), ADD, SUBTRACT, MULTIPLY, DIVIDE

Data types: BINARY, COMP, COMP-4

Options: TRUNC(STD)

Conditions: In all cases

V4 behavior: Use an expensive divide operation to correct digits back to PIC specification

V6 behavior: Only use divide when actually required (in cases of overflow).

Source Example:
1 b5v2a pic s9(5)v9(2) comp.
1 b5v2b pic s9(5)v9(2) comp.

COMPUTE b5v2a = b5v2a + b5v2b

Performance: V6 is 75% faster than V4

Large binary arithmetic

Statement: COMPUTE (+ | - | * | /), ADD, SUBTRACT, MULTIPLY, DIVIDE

Data types: BINARY, COMP, COMP-4

Options: TRUNC(STD)

Conditions: Intermediate results exceed 9 digits

V4 behavior: Arithmetic performed piecewise and converted to packed decimal

V6 behavior: Arithmetic performed in 64-bit registers

Source Example:
1 b8v2a pic s9(8)v9(2) comp.
1 b8v2b pic s9(9)v9(2) comp.

Compute b8v2a = b8v2a + b8v2b.

Performance: V6 is 93% faster than V4

Negation of decimal values

Statement: COMPUTE (-), SUBTRACT

Data types: COMP-3, DISPLAY, NATIONAL

Options: Default

Conditions: In all cases

V4 behavior: Treat as any other subtract from zero

V6 behavior: Recognize as a special case negate operation

Source Example:
1 p7v2a pic s9(7)v9(2) comp-3.
1 p7v2b pic s9(7)v9(2) comp-3.

Compute p7v2b = - p7v2a.

Performance: V6 is 26% faster than V4

Fusing DIVIDE GIVING REMAINDER

Statement: DIVIDE

Data types: COMP-3, DISPLAY

Options: OPT(1 | 2)

Conditions: Both the remainder and the quotient of a division are being used

V4 behavior: Separate divide and remainder computations

V6 behavior: Uses a single DP instruction, and recovers both the remainder and the quotient

Source Example:
01 A COMP-3 PIC S9(15).
01 B COMP-3 PIC S9(15).
01 C COMP-3 PIC S9(15).
01 D COMP-3 PIC S9(15).

DIVIDE A BY B GIVING C REMAINDER D

Performance: V6 is 2% faster than V4