> I've taken to defining functions in header files to take advantage of both > (we don't use IPA).
Looking at the code generated by the XLC compiler, I see that it sometimes (often?) in-lines functions even when they are defined in the (same, obviously) implementation file. Charles -----Original Message----- From: IBM Mainframe Discussion List [mailto:[email protected]] On Behalf Of David Crayford Sent: Sunday, January 13, 2019 8:47 PM To: [email protected] Subject: Re: Unreadable code (Was: Concurrent Server Task Dispatch issue multitasking issue) On 14/01/2019 6:06 am, Ed Jaffe wrote: > On 1/13/2019 4:08 AM, David Crayford wrote: >> On 13/01/2019 7:06 pm, Tony Thigpen wrote: >>> I have seen some reports that current C compilers, which understand >>> the z-hardware pipeline, can actually produce object that is faster >>> running than an assembler. Mainly because no sane assembler >>> programmer would produce great pipe-line code because it would be >>> un-maintanable. >>> >> It's well established that that's been true for a well over a decade >> now. Not just C but all compilers including COBOL which got a new >> optimizer a few releases back. > > > Far, far less true now than it used to be. > Good to hear. The best optimization is done in hardware where you don't have to recompile. Followed by a JIT. > Back in the old days, things ran a lot faster if you interleaved > unrelated things in an "unfriendly" way. For example, this code fragment: > > | LGF R0,Field1 Increment Field1 > | AGHI R0,1 (same) > | ST R0,Field1 (same) > | LGF R0,Field2 Increment Field2 > | AGHI R0,1 (same) > | ST R0,Field2 (same) > | LGF R0,Field3 Increment Field3 > | AGHI R0,1 (same) > | ST R0,Field3 (same) > | LGF R0,Field4 Increment Field4 > | AGHI R0,1 (same) > | ST R0,Field4 (same) > > ran much faster when coded this way (which is not how a programmer > would usually write things): > > | LGF R0,Field1 Increment Field1 > | LGF R1,Field2 Increment Field2 > | LGF R2,Field3 Increment Field3 > | LGF R3,Field4 Increment Field4 > | AGHI R0,1 (same) > | AGHI R1,1 (same) > | AGHI R2,1 (same) > | AGHI R3,1 (same) > | ST R0,Field1 (same) > | ST R1,Field2 (same) > | ST R2,Field3 (same) > | ST R3,Field5 (same) > > But once OOO execution came on the scene with z196, you could get the > same enhanced performance from this easy-to-code and easy-to-read > version: > > | LGF R0,Field1 Increment Field1 > | AGHI R0,1 (same) > | ST R0,Field1 (same) > | LGF R1,Field2 Increment Field2 > | AGHI R1,1 (same) > | ST R1,Field2 (same) > | LGF R2,Field3 Increment Field3 > | AGHI R2,1 (same) > | ST R2,Field3 (same) > | LGF R3,Field4 Increment Field4 > | AGHI R3,1 (same) > | ST R3,Field4 (same) > > These days, many performance improvements are realized by the compiler > using newer instructions that replace older ones. For example, on z10 > and higher, this very same code can be replaced with: > > | ASI Field1,1 Increment Field1 > | ASI Field2,1 Increment Field1 > | ASI Field3,1 Increment Field1 > | ASI Field4,1 Increment Field1 > IIRC, the interleaved instruction scheduling was to mitigate the AGI problem? In my experienced the two optimizations that make the most difference are function inlining and loop unrolling. I've taken to defining functions in header files to take advantage of both (we don't use IPA). ---------------------------------------------------------------------- For IBM-MAIN subscribe / signoff / archive access instructions, send email to [email protected] with the message: INFO IBM-MAIN
