Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.compilers > #613 > unrolled thread
| Started by | Robert AH Prins <robert@prino.org> |
|---|---|
| First post | 2012-04-22 18:57 +0000 |
| Last post | 2012-09-30 10:45 +1000 |
| Articles | 17 — 4 participants |
Back to article view | Back to comp.compilers
Decades of compiler technology and what do we get? Robert AH Prins <robert@prino.org> - 2012-04-22 18:57 +0000
Re: Decades of compiler technology and what do we get? Robert AH Prins <robert@prino.org> - 2012-04-22 22:14 +0000
Re: PL/I nostalgia, was Decades of compiler technology and what do we get? glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2012-04-23 00:03 +0000
Re: PL/I nostalgia "robin" <robin51@dodo.com.au> - 2012-04-25 09:07 +1000
Re: PL/I nostalgia glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2012-04-24 23:52 +0000
Re: PL/I nostalgia "robin" <robin51@dodo.com.au> - 2012-04-28 21:30 +1000
Re: PL/I nostalgia glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2012-04-28 16:11 +0000
Re: PL/I nostalgia Robert A Duff <bobduff@shell01.TheWorld.com> - 2012-04-29 10:16 -0400
Re: PL/I code "robin" <robin51@dodo.com.au> - 2012-05-05 00:45 +1000
Re: PL/I code glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2012-05-05 05:20 +0000
Re: Fortran calls, was PL/I code glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2012-05-06 05:13 +0000
Re: Archaic hardware (was Fortran calls) "robin" <robin51@dodo.com.au> - 2012-05-09 10:46 +1000
Re: PL/I nostalgia "robin" <robin51@dodo.com.au> - 2012-09-19 11:04 +1000
Re: PL/I nostalgia glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2012-09-19 03:56 +0000
Re: PL/I nostalgia "robin" <robin51@dodo.com.au> - 2012-09-21 13:53 +1000
Re: PL/I nostalgia glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2012-09-21 07:00 +0000
Re: PL/I nostalgia "robin" <robin51@dodo.com.au> - 2012-09-30 10:45 +1000
| From | Robert AH Prins <robert@prino.org> |
|---|---|
| Date | 2012-04-22 18:57 +0000 |
| Subject | Decades of compiler technology and what do we get? |
| Message-ID | <12-04-070@comp.compilers> |
On Apr 22, 12:58 pm, "HeyBub" <hey...@NOSPAMgmail.com> wrote in bit.listserv.ibm-main: > > Nomen Nescio wrote: > > > > >> Then, as I said, write the damn thing in assembly language. > > > > > There isn't any need. We're fixing existing COBOL and it's easy to > > > fix. Just take stuff out of loops that doesn't belong there! It > > > works great.. > > > > Is there still a compiler out there that doesn't change: > > > > PERFORM My-Many TIMES > > MOVE 10 TO My-Constant > > [do something else] > > END PERFORM. > > > > to > > > > MOVE 10 TO My-Constant > > PERFORM My-Many TIMES > > [do something else] > > END-PERFORM. > > > > ??? To which yours truly replied: > Oh yes there is, that miracle of a compiler technology called > Enterprise PL/I V3R9... > > 70.0 19 1 do i = 1 to 10; > 71.0 20 1 1 do j = 1 to 10; > 72.0 21 1 2 t = 'Oops'; > 73.0 22 1 2 put skip list(substr(t, 1, 1)); > 74.0 23 1 2 end; > 75.0 24 1 1 end; > > 0000B2 4100 0001 000070 | LA r0,1 > 0000B6 5000 D0CC 000070 | ST r0,I(,r13,204) > 0000BA A70E 000A 000070 | CHI r0,H'10' > 0000BE A724 0063 000070 | JH @1L8 > > 0000C2 000070 | @1L2 DS 0H > 0000C2 4100 0001 000071 | LA r0,1 > 0000C6 5000 D0D0 000071 | ST r0,J(,r13,208) > 0000CA A70E 000A 000071 | CHI r0,H'10' > 0000CE A724 0051 000071 | JH @1L10 > > 0000D2 000071 | @1L5 DS 0H > 0000D2 D203 D0D4 700C 000072 | MVC T(4,r13,212),'Oops'(r7,12) <=== Oops... (wrapped) > 0000D8 4110 D0D8 000072 | LA r1,T(,r13,216) > 0000DC 5010 D180 000072 | ST r1,#STRTEMP1(,r13,384) > 0000E0 9240 1000 000072 | MVI T(r1,0),64 > 0000E4 D219 1001 1000 000072 | MVC T(26,r1,1),T(r1,0) > 0000EA 4100 D100 000073 | LA r0,_temp2(,r13,256) > 0000EE 5000 D170 000073 | ST r0,_temp3(,r13,368) > 0000F2 E544 D12C 4E48 000073 | MVHHI _temp2(r13,300),H'20040' > 0000F8 5800 6004 000073 | L r0,SYSPRINT(,r6,4) > 0000FC 5000 D16C 000073 | ST r0,_temp3(,r13,364) > 000100 E54C D100 0001 000073 | MVHI _temp2(r13,256),H'1' > 000106 4100 D168 000073 | LA r0,_temp3(,r13,360) > 00010A 58F0 3008 000073 | L r15,=V(IBMQOFNT)(,r3,8) > 00010E 4110 D098 000073 | LA r1,#MX_TEMP1(,r13,152) > 000112 5000 D098 000073 | ST r0,#MX_TEMP1(,r13,152) > 000116 0DEF 000073 | BASR r14,r15 > > 000118 4100 6008 000073 | LA r0,_Dsc_000001(,r6,8) > 00011C 5000 D11C 000073 | ST r0,_temp2(,r13,284) > 000120 4100 7010 000073 | LA r0,'..'(,r7,16) > 000124 5000 D118 000073 | ST r0,_temp2(,r13,280) > 000128 4100 D0D4 000073 | LA r0,T(,r13,212) > 00012C 5000 D114 000073 | ST r0,_temp2(,r13,276) > 000130 9220 D12E 000073 | MVI _temp2(r13,302),32 > 000134 4100 D168 000073 | LA r0,_temp3(,r13,360) > 000138 58F0 300C 000073 | L r15,=V(IBMQOFPT)(,r3,12) > 00013C 4110 D098 000073 | LA r1,#MX_TEMP1(,r13,152) > 000140 5000 D098 000073 | ST r0,#MX_TEMP1(,r13,152) > 000144 0DEF 000073 | BASR r14,r15 > > 000146 9201 D12E 000073 | MVI _temp2(r13,302),1 > 00014A 4100 D168 000073 | LA r0,_temp3(,r13,360) > 00014E 58F0 300C 000073 | L r15,=V(IBMQOFPT)(,r3,12) > 000152 4110 D098 000073 | LA r1,#MX_TEMP1(,r13,152) > 000156 5000 D098 000073 | ST r0,#MX_TEMP1(,r13,152) > 00015A 0DEF 000073 | BASR r14,r15 > > 00015C 000074 | @1L6 DS 0H > 00015C 000074 | @1L11 DS 0H > 00015C 5800 D0D0 000074 | L r0,J(,r13,208) > 000160 A70A 0001 000074 | AHI r0,H'1' > 000164 5000 D0D0 000074 | ST r0,J(,r13,208) > 000168 A70E 000A 000074 | CHI r0,H'10' > 00016C A7D4 FFB3 000074 | JNH @1L5 > > 000170 000074 | @1L7 DS 0H > 000170 000074 | @1L10 DS 0H > 000170 000075 | @1L3 DS 0H > 000170 000075 | @1L9 DS 0H > 000170 5800 D0CC 000075 | L r0,I(,r13,204) > 000174 A70A 0001 000075 | AHI r0,H'1' > 000178 5000 D0CC 000075 | ST r0,I(,r13,204) > 00017C A70E 000A 000075 | CHI r0,H'10' > 000180 A7D4 FFA1 000075 | JNH @1L2 > > 000184 000075 | @1L4 DS 0H > 000184 000075 | @1L8 DS 0H > > And don't let me start about IBM's PL/I for Windoze product, which in > many cases generates code that is as "good" as the code generated by > Turbo Pascal in the mid 1980'ies... (Then again, nobody uses it, so > who cares) > > And yes, IBM used to have a compiler that was capable of recognizing > this (to a certain extent), the venerable OS PL/I V2.3.0, predating > Enterprise PL/I by about a decade(?)... > > You might also want to count the number of assembler statements in > the inner loop above and compare it with the number in the inner loop > below. (And then you may start to cry...) > > 17 1 0 DO I = 1 TO 10; > 18 1 1 DO J = 1 TO 10; > 19 1 2 T = 'Oops'; > 20 1 2 PUT SKIP LIST(SUBSTR(T, 1, 1)); > 21 1 2 END; > 22 1 1 END; > > * STATEMENT NUMBER 17 > 0000C6 58 50 3 060 L 5,96(0,3) > 0000CA 50 50 D 0C4 ST 5,I > 0000CE CL.4 EQU * > > * STATEMENT NUMBER 18 > 0000CE 58 B0 3 05C L 11,92(0,3) > 0000D2 58 A0 3 060 L 10,96(0,3) > 0000D6 18 5A LR 5,10 > 0000D8 50 50 D 0C0 ST 5,J > > * INITIALIZATION CODE FOR OPTIMIZED LOOP FOLLOWS > > * CODE MOVED FROM STATEMENT NUMBER 19 <==== Yes we can^H^H^Hcould... > 0000DC D2 03 D 0C8 3 08C MVC T(4),140(3) > > * CONTINUATION OF STATEMENT NUMBER 18 > 0000E2 92 40 D 0CC MVI T+4,X'40' > 0000E6 D2 19 D 0CD D 0CC MVC T+5(26),T+4 > 0000EC CL.6 EQU * > > * STATEMENT NUMBER 19 > > * STATEMENT NUMBER 20 > 0000EC 41 70 D 110 LA 7,272(0,13) > 0000F0 50 70 3 07C ST 7,124(0,3) > 0000F4 18 17 LR 1,7 > 0000F6 50 10 D 108 ST 1,264(0,13) > 0000FA 92 40 D 121 MVI 289(13),X'40' > 0000FE 41 10 3 078 LA 1,120(0,3) > 000102 58 F0 3 02C L 15,A..IBMBSIOE > 000106 05 EF BALR 14,15 > 000108 D2 07 D 138 3 048 MVC 312(8,13),72(3) > 00010E 41 40 D 0C8 LA 4,T > 000112 50 40 D 138 ST 4,312(0,13) > 000116 41 E0 D 138 LA 14,312(0,13) > 00011A 41 F0 3 040 LA 15,DED..T > 00011E 58 10 D 108 L 1,264(0,13) > 000122 90 EF 1 000 STM 14,15,0(1) > 000126 58 F0 3 034 L 15,A..IBMBSLOA > 00012A 05 EF BALR 14,15 > 00012C 58 10 D 108 L 1,264(0,13) > 000130 58 F0 3 030 L 15,A..IBMBSIOT > 000134 05 EF BALR 14,15 > > * STATEMENT NUMBER 21 > 000136 87 5A 2 02A BXLE 5,10,CL.6 > 00013A 50 50 D 0C0 ST 5,J > > * CODE MOVED FROM STATEMENT NUMBER 18 > > * STATEMENT NUMBER 22 > 00013E 58 50 D 0C4 L 5,I > 000142 5A 50 3 060 A 5,96(0,3) > 000146 50 50 D 0C4 ST 5,I > 00014A 49 50 3 042 CH 5,66(0,3) > 00014E 47 C0 2 00C BNH CL.4 > > * CODE MOVED FROM STATEMENT NUMBER 17 > > * STATEMENT NUMBER 23 > > Sigh... Maybe the experts in this group would like to give their thoughts about the why of this apparently/seemingly/obviously ridiculous(?) regression? Robert -- Robert AH Prins robert(a)prino(d)org [The conventional wisdom is that COBOL programs are all I/O bound, so the speed of the object code is not a big deal. There are plenty of other compilers that can optimize this kind of stuff. -John]
[toc] | [next] | [standalone]
| From | Robert AH Prins <robert@prino.org> |
|---|---|
| Date | 2012-04-22 22:14 +0000 |
| Message-ID | <12-04-072@comp.compilers> |
| In reply to | #613 |
On 2012-04-22 18:57, Robert AH Prins wrote: > On Apr 22, 12:58 pm, "HeyBub"<hey...@NOSPAMgmail.com> wrote in > bit.listserv.ibm-main: > > [The conventional wisdom is that COBOL programs are all I/O bound, so > the speed of the object code is not a big deal. There are plenty of > other compilers that can optimize this kind of stuff. -John] As it turns out our test compiles add an OPT(0) after all programmer supplied options "because that takes less CPU..." My comment that this means that production programs are never the same as the ones that have been tested was dismissed with a "We have done this for years without anyone ever having a problem with it." Submitting from SDSF with altered JCL does produce rather better code, so I stand corrected (again, I'm losing it, rapidly...) Apologies to all, at least for the z/OS part! However, I'm not going to retract my remarks about the PL/I for Windows compiler. Robert -- Robert AH Prins robert(a)prino(d)org
[toc] | [prev] | [next] | [standalone]
| From | glen herrmannsfeldt <gah@ugcs.caltech.edu> |
|---|---|
| Date | 2012-04-23 00:03 +0000 |
| Subject | Re: PL/I nostalgia, was Decades of compiler technology and what do we get? |
| Message-ID | <12-04-077@comp.compilers> |
| In reply to | #613 |
(snip, someone wrote) > > > > There isn't any need. We're fixing existing COBOL and it's easy to > > > > fix. Just take stuff out of loops that doesn't belong there! It > > > > works great.. (big snip, including generated code listing from PL/I) > Maybe the experts in this group would like to give their thoughts about > the why of this apparently/seemingly/obviously ridiculous(?) regression? > [The conventional wisdom is that COBOL programs are all I/O bound, so > the speed of the object code is not a big deal. There are plenty of > other compilers that can optimize this kind of stuff. -John] It has always seemed to me that PL/I would have been more successful if the early compilers generated faster code (and ran faster, too). It might have been that too much of the above was adopted, along with other COBOL features, by PL/I. There are many things that other languages, such as Fortran, traditionally didn't let you do, because they might run too slow, but that PL/I allowed. (Many of those have now been added to Fortran.) Of all languages, I think I still find PL/I the most fun to write in, though not necessarily best for the problems I actually need done. -- glen
[toc] | [prev] | [next] | [standalone]
| From | "robin" <robin51@dodo.com.au> |
|---|---|
| Date | 2012-04-25 09:07 +1000 |
| Subject | Re: PL/I nostalgia |
| Message-ID | <12-04-081@comp.compilers> |
| In reply to | #620 |
From: glen herrmannsfeldt <gah@ugcs.caltech.edu>
Date: Monday, 23 April 2012 11:45
>It has always seemed to me that PL/I would have been more successful
>if the early compilers generated faster code (and ran faster, too).
>
>It might have been that too much of the above was adopted, along with
>other COBOL features, by PL/I. There are many things that other
>languages, such as Fortran, traditionally didn't let you do, because
>they might run too slow, but that PL/I allowed.
FORTRAN was developed by 1956.
PL/I was developed by 1966.
In the decade after 1956, many deficiencies had been identified in FORTRAN;
some of its statements were pretty crude.
Similar comments may be made about COBOL.
While some features of both FORTRAN and COBOL were adopted in PL/I,
many new features were added, including (but not limited to) recursive procedures
and dynamic allocation (already in Algol).
Of those features adapted from the older languages, arbitrary restrictions
were removed, making it much easier to write programs.
One other point is that the size of machines had increased significantly
in that early decade, permitting more language features to be incorporated
in PL/I.
PL/I can be considered to be the first general-purpose language.
As to code generation of the early PL/I compilers, that code was reasonably efficient.
I would agree, however, there were certain situations where much faster code
could have been generated, but that opportunity was not taken.
I refer to operations involving whole arrays or array sections.
For instance, where an operation involved a whole array,
IBM's first compiler, PL/I-F, could have optimised a matrix statement
(trivial example, A=B; where all elements of A and B are accessed)
to a single loop, instead of the two equivalent loops that were actually used:
do i = 1 to m;
do j = 1 to n;
A(i,j) = B(i,j);
end;
end;
Four years later, IBM produced their Optimising Compiler and Checkout Compiler
(c. 1970).
>(Many of those have now been added to Fortran.)
Some have, but others have not.
For example, recent discussion in comp.lang.fortran evolved around a suitable
Fortran procedure to convert an integer to a string.
In PL/I, it requires a simple statement, s = i;
Some of the code examples offered for Fortran were as long as about 50 statements;
other shorter ones that used internal I/O failed to work when incorporated in a function procedure,
because that facility requires recursive I/O -- something that is not permitted.
Another of the same category is the Fortran list of string constants.
In Fortran, all such constants must have the same length,
as the array with which such a list is associated is not varying --
all array elements must have the same length.
[Considering what a rush job PL/I was, it's a remarkably good language. -John]
[toc] | [prev] | [next] | [standalone]
| From | glen herrmannsfeldt <gah@ugcs.caltech.edu> |
|---|---|
| Date | 2012-04-24 23:52 +0000 |
| Subject | Re: PL/I nostalgia |
| Message-ID | <12-04-082@comp.compilers> |
| In reply to | #624 |
robin <robin51@dodo.com.au> wrote: (snip, I wrote) >>It has always seemed to me that PL/I would have been more successful >>if the early compilers generated faster code (and ran faster, too). (previous snip on I/O bound COBOL, and not worrying about CPU time.) >>It might have been that too much of the above was adopted, along with >>other COBOL features, by PL/I. There are many things that other >>languages, such as Fortran, traditionally didn't let you do, because >>they might run too slow, but that PL/I allowed. > FORTRAN was developed by 1956. > PL/I was developed by 1966. > In the decade after 1956, many deficiencies had been identified > in FORTRAN; some of its statements were pretty crude. This is true, but not so important for this question. Fortran didn't allow for recursion until 1990, and even then you had to have the RECURSIVE attribute. Compilers could still generate non-recursive code without the attribute. There is overhead to the calling sequence to allow for recursion, at least on most systems. It was usual for Fortran compilers to use static allocation through Fortran 77. (Some rules were written specifically to allow for it.) On machines without a call stack, there is also overhead for that, in addition to local variable allocation. Even more for PL/I, the ability to do multi-tasking adds more complications that have more overhead. > Similar comments may be made about COBOL. As noted, this was in response to a suggestion that COBOL programs were I/O bound, and so there was less need for CPU time optimization. On the other hand, I/O optimizations such as locate mode I/O would have been more important for COBOL. > While some features of both FORTRAN and COBOL were adopted > in PL/I, many new features were added, including (but not > limited to) recursive procedures and dynamic allocation > (already in Algol). > Of those features adapted from the older languages, arbitrary > restrictions were removed, making it much easier to write programs. And much easier to write slow programs. Simple PL/I expressions can require temporary arrays. (Usually with a warning message.) That didn't happen to Fortran until 1990, when machines were much faster. > One other point is that the size of machines had increased > significantly in that early decade, permitting more language > features to be incorporated in PL/I. But the window was fairly small. IBM had originally expected to replace Fortran (and maybe COBOL) with PL/I. The compiler arrived late, ran slow, and generated much slower code. > PL/I can be considered to be the first general-purpose language. > As to code generation of the early PL/I compilers, that code > was reasonably efficient. For many scientific problems, reasonably isn't enough. > I would agree, however, there were certain situations where much > faster code could have been generated, but that opportunity was > not taken. > I refer to operations involving whole arrays or array sections. > For instance, where an operation involved a whole array, > IBM's first compiler, PL/I-F, could have optimised a matrix statement > (trivial example, A=B; where all elements of A and B are accessed) > to a single loop, instead of the two equivalent loops that were actually used: > do i = 1 to m; > do j = 1 to n; > A(i,j) = B(i,j); > end; > end; In some cases you can do that, but it isn't so easy in a subroutine, when the array might not be contiguous. Also, since array operations were added to Fortran, they are one of the biggest causes for complaints about slow programs. One reason is that people sometimes write array expressions that require much more computation than they would written as loops. PL/I only supports call-by-descriptor for arrays and strings. That is good, but has more overhead. For today's machines, that isn't so bad, but on slower machines in the early days, it may have been too much. > Four years later, IBM produced their Optimising Compiler and > Checkout Compiler (c. 1970). >>(Many of those have now been added to Fortran.) > Some have, but others have not. > For example, recent discussion in comp.lang.fortran evolved > around a suitable Fortran procedure to convert an integer to a string. > In PL/I, it requires a simple statement, s = i; It is one of the fun features of PL/I, but not so often needed in production programs. I do remember in high-school writing a PL/I DO loop with CHAR variables for the DO variable, and the start, end, and increment value. (It is slightly interesting, as a string compare is used in the loop test.) > [Considering what a rush job PL/I was, it's a remarkably good > language. -John] I didn't know about that until recently when I bought "History of Programming Languages", edited by Richard L. Wexelblat, which covers the timeline for the PL/I language specification. (Writing the actual compiler was a separate timeline.) As well as I can tell, it was October 1963 that the decision to design a new language, instead of going to Fortran VI, was final, and the group formed to write the specification. They were told that it needed to be done by December 1963. In December, it was extended to January 1964, and then slipped to February. Then there is the comment: "While this can never be proven, it is clear that much of the long and demanding work in PL/I language development would have been made much easier ahd the designing committee been given six months or a year at the beginning to lay down a carefully defined language base." I wonder how much time has now been spent by committees working on the Fortran standard. -- glen
[toc] | [prev] | [next] | [standalone]
| From | "robin" <robin51@dodo.com.au> |
|---|---|
| Date | 2012-04-28 21:30 +1000 |
| Subject | Re: PL/I nostalgia |
| Message-ID | <12-04-084@comp.compilers> |
| In reply to | #625 |
From: "glen herrmannsfeldt" <gah@ugcs.caltech.edu> Sent: Wednesday, 25 April 2012 9:52 AM > robin <robin51@dodo.com.au> wrote: > > (snip, glen herrmannsfeldt wrote) >>>It has always seemed to me that PL/I would have been more successful >>>if the early compilers generated faster code (and ran faster, too). > > (previous snip on I/O bound COBOL, and not worrying about CPU time.) > >>>It might have been that too much of the above was adopted, along with >>>other COBOL features, by PL/I. There are many things that other >>>languages, such as Fortran, traditionally didn't let you do, because >>>they might run too slow, but that PL/I allowed. > >> FORTRAN was developed by 1956. >> PL/I was developed by 1966. >> In the decade after 1956, many deficiencies had been identified >> in FORTRAN; some of its statements were pretty crude. > > This is true, but not so important for this question. It is fundamentally important, since you raised it 2 paras ago, as to what was put in PL/I and why. FORTRAN was deficient in many areas, including I/O, its use of EQUIVALENCE and COMMON, character strings, and DO loops. Algol already had recursion; FORTRAN didn't, and that deficiency made it difficult to write algorithms that were general and which dealt with dynamic arrays that, in scientific computation, was a pressing need. > Fortran didn't allow for recursion until 1990, and even then you had > to have the RECURSIVE attribute. Compilers could still generate > non-recursive code without the attribute. All that's irrelevant. > There is overhead to the calling sequence to allow for recursion, at > least on most systems. It was usual for Fortran compilers to use > static allocation through Fortran 77. (Some rules were written > specifically to allow for it.) On machines without a call stack, there > is also overhead for that, in addition to local variable allocation. The overhead is small, and in many programs, negligible. > Even more for PL/I, the ability to do multi-tasking adds more > complications that have more overhead. An irrelevant consideration in this discussion. >> Similar comments may be made about COBOL. > > As noted, this was in response to a suggestion that COBOL programs > were I/O bound, and so there was less need for CPU time optimization. Any program can be I/O bound. There are, nevertheless, COBOL programs that are not I/O bound. Even in ones that are, time can be saved through optimisation, as a reduction in the run-time of the computational components that cannot be overlapped with I/O reduces overall time. > On the other hand, I/O optimizations such as locate mode I/O would > have been more important for COBOL. That isn't an "optimisation", it's a programming strategy. >> While some features of both FORTRAN and COBOL were adopted >> in PL/I, many new features were added, including (but not >> limited to) recursive procedures and dynamic allocation >> (already in Algol). > >> Of those features adapted from the older languages, arbitrary >> restrictions were removed, making it much easier to write programs. > > And much easier to write slow programs. No, it does not. The removal of arcane restrictions made it easier to write error-free programs. It's always easy to write slow programs, even in FORTRAN. The restrictions removed from the older languages, however, made it easier to write faster programs. It also made it easier to write programs in shorter time than before. Furthermore, the necessity in FORTRAN of having all storage as static meant that programs employing large arrays or lots of arrays used the processor inefficiently in that the executable programs tied up more memory than was necessary. Compared to PL/I, which provides dynamic arrays, considerably less run-time memory was required. [In case it is thought from the above that PL/I provides only dynamic arrays, may I point out that PL/I provides dynamic and static arrays, as well as controlled arrays.] > Simple PL/I expressions can > require temporary arrays. (Usually with a warning message.) > > That didn't happen to Fortran until 1990, when machines were much > faster. That's relative, and in any case irrelevant. Machines were much faster in 1966 compared to 1956. >> One other point is that the size of machines had increased >> significantly in that early decade, permitting more language >> features to be incorporated in PL/I. > > But the window was fairly small. IBM had originally expected to > replace Fortran (and maybe COBOL) with PL/I. The compiler arrived > late, ran slow, and generated much slower code. You're wrong on both counts. The hardware was late. All the compilers were late. The code from IBM's PL/I was just as good as from IBM's Fortran compilers on the machine that we had. I still have the results somewhere of test runs in FORTRAN and PL/I. It was the link editor that took longer with PL/I than with FORTRAN. >> PL/I can be considered to be the first general-purpose language. > >> As to code generation of the early PL/I compilers, that code >> was reasonably efficient. > > For many scientific problems, reasonably isn't enough. I should have been more explicit. Code generation from IBM's FORTRAN compilers on the machine that we had was reasonably efficient too. What is just as important is what happens when a program runs. FORTRAN programs often halted (division by zero, floating-point overflow) without any indication of where or why they halted. Even were a FORTRAN program to run faster than a PL/I program, any such "saving" would be more than lost by having to re-run the FORTRAN program to try to find where and why it stopped. There was (and still is) no need to re-run the PL/I program to do that, because the location and the reason were printed when the PL/I program halted. Given that it was also possible to print the values of any variables along with the above information, the debugging/development of the program saved a good deal of machine time. On the issue of whether PL/I was faster or slower than FORTRAN, it's clear that those making timing comparisons did not know how to write or to run PL/I programs. One published account (D. J. Kewley, "A Comparison between Pascal, FORTRAN, and PL/I", ACJ, Feb. 1981, pp 27-8) claimed that Pascal was faster than PL/I, and the author produced timing figures to "prove" it. The author failed to specify the PL/I option "REORDER" that would permit optimisation to take place. Furthermore, he compared one Pascal program performing complex arithmetic, with a PL/I program doing the same. Not supporting complex arithmetic, the Pascal program simulated those operations. When the PL/I version was rewritten using complex arithmetic, and with the REORDER option on the PROCEDURE statement, a 47% increase in speed was obtained. (see my refutation, ACJ, Aug. 1981, p. 107) In his published accounts of timing comparisons between COBOL, PL/I, and FORTRAN, A. B. Tucker (Programming Languages", McGraw-Hill, 1977) neglected to specify the REORDER option. This neglect again prevented the PL/I compiler from optimising the object programs, and therefore invalidated his timing and code comparisons with COBOL and FORTRAN. In P. J. Jaliks, "COBOL vs PL/I: Some Performance Comparisons", CACM, April 1984, pp. 216-221, similar errors were made for the PL/I version. In particular, one PL/I program ran two to three times slower on account of inappropriate data declarations. More recently, R. H. Prins criticized IBM's Enterprise PL/I compiler for optimising poorly. He subsequently retracted that criticism when he discovered that he had been compiling the program with OPT(0) -- that is, no optimisation ! FORTRAN programmers tended to mimic FORTRAN style in their PL/I code that was inappropriate in PL/I. That caused PL/I programs to run slower than they should have. >> I would agree, however, there were certain situations where much >> faster code could have been generated, but that opportunity was >> not taken. > >> I refer to operations involving whole arrays or array sections. >> For instance, where an operation involved a whole array, >> IBM's first compiler, PL/I-F, could have optimised a matrix statement >> (trivial example, A=B; where all elements of A and B are accessed) >> to a single loop, instead of the two equivalent loops that were actually used: >> do i = 1 to m; >> do j = 1 to n; >> A(i,j) = B(i,j); >> end; >> end; > > In some cases you can do that, but it isn't so easy in a subroutine, > when the array might not be contiguous. IIRC, in IBM's F-compiler, elements in arrays were contiguous, even in subroutines. [Even were that not so, a single loop suffices.] > Also, since array operations were added to Fortran, they are one of > the biggest causes for complaints about slow programs. Fortran 90 introduced array features (in a manner different from PL/I) that forces temporary arrays to be created, and which results in Fortran programs running slower than equivalent features not using the new array features. > One reason is that people sometimes write array expressions that > require much more computation than they would written as loops. That's their choice. > PL/I only supports call-by-descriptor for arrays and strings. That is > good, but has more overhead. Than what? Not having descriptors? Descriptors are necessary to deal with dynamic arrays. Without descriptors, it would be back to pre-Fortran 90, where only the address of the first element of an array was typically passed. That arrangement impeded or prevented information about a FORTRAN array being made available to a subroutine. > For today's machines, that isn't so bad, > but on slower machines in the early days, it may have been too much. The "overheads" of passing a descriptor to a subroutine were (and still are) minimal. >> Four years later, IBM produced their Optimising Compiler and >> Checkout Compiler (c. 1970). > >>>(Many of those have now been added to Fortran.) > >> Some have, but others have not. >> For example, recent discussion in comp.lang.fortran evolved >> around a suitable Fortran procedure to convert an integer to a string. > >> In PL/I, it requires a simple statement, s = i; > > It is one of the fun features of PL/I, but not so often needed in > production programs. It's been a recurring chestnut in FORTRAN/Fortran for the past 40 years. It's an important feature of any program. It's not relevant to mention "production" programs. Whether a program runs once or a hundred times is irrelevant. Conversion to a character string is something that's used often in PL/I in conjunction with the TRIM function to remove leading blanks. [Irrelevant material omitted.] >> [Considering what a rush job PL/I was, it's a remarkably good >> language. -John] > > I didn't know about that until recently when I bought "History > of Programming Languages", edited by Richard L. Wexelblat, which > covers the timeline for the PL/I language specification. (Writing > the actual compiler was a separate timeline.) > > As well as I can tell, it was October 1963 that the decision to > design a new language, instead of going to Fortran VI, was final, > and the group formed to write the specification. They were told > that it needed to be done by December 1963. In December, it was > extended to January 1964, and then slipped to February. That those early dates slipped is irrelevant, as the S/360 wasn't even announced until 1964. In any case, a slippage by a few months was unimportant. > Then there is the comment: > > "While this can never be proven, it is clear that much of the > long and demanding work in PL/I language development would have > been made much easier ahd the designing committee been given > six months or a year at the beginning to lay down a carefully > defined language base." Work on designs for the new language had already been in progress prior to October 1963, so at that point much was known as to what would be put into PL/I (or New Programming Language as it was called before it was PL/I.) [The code fron PL/I F was comparablw to Fortran G, but much worse than Fortran H. The PL/I optimizing compiler's code was better, but still not as good as Fortran H and its descendants. -John]
[toc] | [prev] | [next] | [standalone]
| From | glen herrmannsfeldt <gah@ugcs.caltech.edu> |
|---|---|
| Date | 2012-04-28 16:11 +0000 |
| Subject | Re: PL/I nostalgia |
| Message-ID | <12-04-085@comp.compilers> |
| In reply to | #627 |
robin <robin51@dodo.com.au> wrote: (big snip, then I wrote) >> Fortran didn't allow for recursion until 1990, and even then you >> had to have the RECURSIVE attribute. Compilers could still generate >> non-recursive code without the attribute. > All that's irrelevant. There is, at least, more overhead in the procedure entry/exit sequence for recursive routines. Now, since PL/I also has the RECURSIVE attribute the compiler could generate different code in the non-recursive case. OK, to get an actual compiler question into the discussion, are there any compilers that generate non-reentrant code for a language that allows recursion when it isn't being used? (snip) > Furthermore, the necessity in FORTRAN of having all storage > as static meant that programs employing large arrays or lots of > arrays used the processor inefficiently in that the > executable programs tied up more memory than was necessary. > Compared to PL/I, which provides dynamic arrays, considerably > less run-time memory was required. That is true. For a single task system, like many before OS/360 and like OS/360 PCP on smaller system, though, if it fits there isn't much cost to the wasted memory. > [In case it is thought from the above that PL/I provides only > dynamic arrays, may I point out that PL/I provides dynamic > and static arrays, as well as controlled arrays.] I probably lost the thread that the comment was supposed to apply to. In a called procedure, it doesn't matter how the original array was allocated, it is referenced through the dope-vector (call by descriptor). In the case of a local array, the compiler can make some optimizations that it can't make for a procedure argument. Fortran 90 added assumed shape arrays, where the called array gets the shape, most likely through a descriptor similar to that from PL/I. In traversing an array through a descriptor, it isn't so easy to convert to a single loop. Through Fortran 77, the array passing method now called assumed size was usually used. A common way to use assumed size in Fortran was for the called routine to declare the argument as rank one and do all the index calculations internally. Now, as Robin mentioned PL/I often made it easier to write correct programs. Processing a matrix through a rank one array is more difficult to get right. >> Simple PL/I expressions can require temporary arrays. >> (Usually with a warning message.) >> That didn't happen to Fortran until 1990, when machines were much >> faster. > That's relative, and in any case irrelevant. > Machines were much faster in 1966 compared to 1956. There is still much discussion on comp.lang.fortran on the speed difference between array expressions and explicit DO loops. >>> One other point is that the size of machines had increased >>> significantly in that early decade, permitting more language >>> features to be incorporated in PL/I. >> But the window was fairly small. IBM had originally expected to >> replace Fortran (and maybe COBOL) with PL/I. The compiler arrived >> late, ran slow, and generated much slower code. > You're wrong on both counts. The hardware was late. All the > compilers were late. The code from IBM's PL/I was just as good as > from IBM's Fortran compilers on the machine that we had. I still have > the results somewhere of test runs in FORTRAN and PL/I. It was the > link editor that took longer with PL/I than with FORTRAN. Certainly the link editor was always slow. If one wrote the same program in PL/I, the result might be close to that from Fortran. If one started using many of the PL/I features, though, it was very easy to get a much slower program. One might, for example, use FIXED DECIMAL variables that require conversion to binary when used as array subscripts. That is, at least, one problem that OS/360 Fortran programmers never had. (snip) > I should have been more explicit. Code generation from IBM's > FORTRAN compilers on the machine that we had was reasonably > efficient too. > What is just as important is what happens when a program runs. > FORTRAN programs often halted (division by zero, floating-point > overflow) without any indication of where or why they halted. OS/360 Fortran has a nice traceback feature. I don't know when it was added, though. On the other hand, in the fairly common branch to a non-existing address, both Fortran and PL/I left you lost. (snip) > One published account (D. J. Kewley, "A Comparison between > Pascal, FORTRAN, and PL/I", ACJ, Feb. 1981, pp 27-8) > claimed that Pascal was faster than PL/I, > and the author produced timing figures to "prove" it. > The author failed to specify the PL/I option "REORDER" that would > permit optimisation to take place. Furthermore, he compared > one Pascal program performing complex arithmetic, with a PL/I > program doing the same. Not supporting complex arithmetic, > the Pascal program simulated those operations. When the PL/I > version was rewritten using complex arithmetic, > and with the REORDER option on the PROCEDURE statement, > a 47% increase in speed was obtained. (see my refutation, ACJ, > Aug. 1981, p. 107) (snip) > FORTRAN programmers tended to mimic FORTRAN style in > their PL/I code that was inappropriate in PL/I. > That caused PL/I programs to run slower than they should have. (snip) >> In some cases you can do that, but it isn't so easy in a subroutine, >> when the array might not be contiguous. > IIRC, in IBM's F-compiler, elements in arrays were contiguous, > even in subroutines. [Even were that not so, a single loop suffices.] PL/I allows array cross sections that can be non-contiguous. I believe some Fortran compilers now generate a test for a contiguous array and then different code to process the two cases. As far as I know, no PL/I compilers do that. (Then again, I haven't looked that carefully.) >> Also, since array operations were added to Fortran, they are one of >> the biggest causes for complaints about slow programs. (snip) >> One reason is that people sometimes write array expressions that >> require much more computation than they would written as loops. > That's their choice. That is true. Still, people seem to like doing it. >> PL/I only supports call-by-descriptor for arrays and strings. >> That is good, but has more overhead. > Than what? Not having descriptors? > Descriptors are necessary to deal with dynamic arrays. > Without descriptors, it would be back to pre-Fortran 90, > where only the address of the first element of an array was > typically passed. The generated code to process assumed size arrays is often faster than assumed shape. In many cases it is a worthwhile tradeoff on today's machines. (snip) >>> [Considering what a rush job PL/I was, it's a remarkably good >>> language. -John] >> I didn't know about that until recently when I bought "History >> of Programming Languages", edited by Richard L. Wexelblat, which >> covers the timeline for the PL/I language specification. (Writing >> the actual compiler was a separate timeline.) >> As well as I can tell, it was October 1963 that the decision to >> design a new language, instead of going to Fortran VI, was final, >> and the group formed to write the specification. They were told >> that it needed to be done by December 1963. In December, it was >> extended to January 1964, and then slipped to February. > That those early dates slipped is irrelevant, as the S/360 wasn't > even announced until 1964. In any case, a slippage by a few months > was unimportant. From that description, they had four months. With the earlier deadline, they would have had to have most of it done in two months. For a language as complicated as PL/I, that isn't much time at all. (snip) > [The code fron PL/I F was comparablw to Fortran G, but much worse than > Fortran H. The PL/I optimizing compiler's code was better, but still > not as good as Fortran H and its descendants. -John] As long as you don't use too many fancy PL/I features, that should be true. Of course you didn't have those features in Fortran IV. There is a tendency to try out new features of a new language, though. -- glen [I got some astonishingly awful code when I tried to use an array of 12 bit fields. As I recall, the code converted the fields to decimal and back, for reasons I could not begin to guess. Also, looking at the manuals in Bitsavers, they were still adding features and optimizations to PL/I F at least as late as 1968. -John]
[toc] | [prev] | [next] | [standalone]
| From | Robert A Duff <bobduff@shell01.TheWorld.com> |
|---|---|
| Date | 2012-04-29 10:16 -0400 |
| Subject | Re: PL/I nostalgia |
| Message-ID | <12-04-086@comp.compilers> |
| In reply to | #628 |
glen herrmannsfeldt <gah@ugcs.caltech.edu> writes: > OK, to get an actual compiler question into the discussion, > are there any compilers that generate non-reentrant code for > a language that allows recursion when it isn't being used? Yes, in the small-machine embedded systems world. On a modern 64-bit machine with efficient addressing based on a stack pointer and/or frame pointer, I suspect it would be a pessimization. Note that recursion isn't the only issue -- there's also multi-threading. - Bob [I expect that on modern machines where code is generally read-only to allow sharing between processes, there's no advantage to non-recursive code. Back in the 1960s, S/360 code typically had a static save area per routine that it used for all its calls, and there was a fair amount of extra complication to save stuff in a stack. -John]
[toc] | [prev] | [next] | [standalone]
| From | "robin" <robin51@dodo.com.au> |
|---|---|
| Date | 2012-05-05 00:45 +1000 |
| Subject | Re: PL/I code |
| Message-ID | <12-05-004@comp.compilers> |
| In reply to | #628 |
From: "glen herrmannsfeldt" <gah@ugcs.caltech.edu> > > (big snip, then I wrote) >>> Fortran didn't allow for recursion until 1990, and even then you >>> had to have the RECURSIVE attribute. Compilers could still generate >>> non-recursive code without the attribute. > >> All that's irrelevant. > > There is, at least, more overhead in the procedure entry/exit > sequence for recursive routines. More overhead, maybe, but how much more? Registers usually have to be saved, a return address has to be preserved somewhere. When the machine has a stack, those things can go on the stack. There appears to be no extra overhead. When the machine does not have a hardware stack, one must be simulated, or, space must be made available for saving those things, at each recursive call. In that case, a request from the OS may need to be made for the storage. The request will add to overhead. But again, how much extra? > Now, since PL/I also has the > RECURSIVE attribute the compiler could generate different code > in the non-recursive case. And did, in the case of PL/I-F, AFIK. BTW, the RECURSIVE attribute was required because of the possibility of independent compilation, for it may not have been otherwise obvious to the compiler that this particular procedure was in some sort of recursive call chain. > OK, to get an actual compiler question into the discussion, > are there any compilers that generate non-reentrant code for > a language that allows recursion when it isn't being used? IBM PL/I for Windows generates different code for procedures that are identical except for the attribute RECURSIVE. Similarly for DR PL/I for DOS. >> Furthermore, the necessity in FORTRAN of having all storage >> as static meant that programs employing large arrays or lots of >> arrays used the processor inefficiently in that the >> executable programs tied up more memory than was necessary. >> Compared to PL/I, which provides dynamic arrays, considerably >> less run-time memory was required. > > That is true. For a single task system, like many before OS/360 and > like OS/360 PCP on smaller system, though, if it fits there isn't much > cost to the wasted memory. Correct as far as it goes, but you've missed the point. Such a program may not run at all on a PCP system owing to the sum of its static storage requirements exceeding available memory. However, in the same system, a similar PL/I program using dynamic memory can run because (1) there is no wasted memory, and (2) the demand for dynamic memory generally means that all the memory is not required at the same time, resulting in significantly less memory requirements. (For instance, storage taken by temporary arrays created in one procedure are given back to the system when the procedure terminates.) On a system like MVT, using excessive storage prevents other programs from being loaded and (possibly) executed concurrently. Where the run-time requirements of a program using static memory are almost as large as available memory, once an MVT-style system decides that the priority of the large program has become high enough, it will stop scheduling small programs, and will permit other running programs to terminate, until all the memory is free to run the large job. >> [In case it is thought from the above that PL/I provides only >> dynamic arrays, may I point out that PL/I provides dynamic >> and static arrays, as well as controlled arrays.] > > I probably lost the thread that the comment was supposed to apply to. > In a called procedure, it doesn't matter how the original array was > allocated, it is referenced through the dope-vector (call by > descriptor). Correct. My remark was just by way of explanation for readers not specially familiar with PL/I. > In the case of a local array, the compiler can make some optimizations > that it can't make for a procedure argument. Like what? I know of no such restrictions in PL/I-F. Nor in Windows PL/I, for that matter. > Fortran 90 added assumed shape arrays, where the called array gets the > shape, most likely through a descriptor similar to that from PL/I. In > traversing an array through a descriptor, it isn't so easy to convert > to a single loop. In Fortran (90 or later), the descriptor holds, or can hold, the stride value. Thus, a called procedure can access non-contiguous elements in a single loop. > Through Fortran 77, the array passing method now called assumed size > was usually used. A common way to use assumed size in Fortran was for > the called routine to declare the argument as rank one and do all the > index calculations internally. But it was also common to use "adjustable" arrays, and to deal with a matrix argument as a matrix dummy argument. > Now, as Robin mentioned PL/I often made it easier to write correct > programs. Processing a matrix through a rank one array is more > difficult to get right. Indeed. >>> Simple PL/I expressions can require temporary arrays. >>> (Usually with a warning message.) > >>> That didn't happen to Fortran until 1990, when machines were much >>> faster. > >> That's relative, and in any case irrelevant. >> Machines were much faster in 1966 compared to 1956. > > There is still much discussion on comp.lang.fortran on the speed > difference between array expressions and explicit DO loops. > >>>> One other point is that the size of machines had increased >>>> significantly in that early decade, permitting more language >>>> features to be incorporated in PL/I. > >>> But the window was fairly small. IBM had originally expected to >>> replace Fortran (and maybe COBOL) with PL/I. The compiler arrived >>> late, ran slow, and generated much slower code. > >> You're wrong on both counts. The hardware was late. All the >> compilers were late. The code from IBM's PL/I was just as good as >> from IBM's Fortran compilers on the machine that we had. I still have >> the results somewhere of test runs in FORTRAN and PL/I. It was the >> link editor that took longer with PL/I than with FORTRAN. > > Certainly the link editor was always slow. If one wrote the same > program in PL/I, the result might be close to that from Fortran. > > If one started using many of the PL/I features, though, it was very > easy to get a much slower program. One might, for example, use FIXED > DECIMAL variables that require conversion to binary when used as array > subscripts. That is, at least, one problem that OS/360 Fortran > programmers never had. Decimal variables were not designed to be used as subscripts. Decimal variables are typically used in holding data for general computation, mostly, but not exclusively, for commercial work. One application I recall was for a large array holding values smaller than 10. Decimal variables were just right for that application because FIXED DECIMAL (1) required only one byte of storage. Compared to FORTRAN, which used 4 bytes for an integer, the large array in PL/I used one-quarter of the storage of its FORTRAN counterpart. That observation also applies to arrays whose values are -1, 0, and 1. >> I should have been more explicit. Code generation from IBM's >> FORTRAN compilers on the machine that we had was reasonably >> efficient too. > >> What is just as important is what happens when a program runs. >> FORTRAN programs often halted (division by zero, floating-point >> overflow) without any indication of where or why they halted. > > OS/360 Fortran has a nice traceback feature. I don't know when it was > added, though. On the other hand, in the fairly common branch to a > non-existing address, both Fortran and PL/I left you lost. Branches to non-existent addresses in PL/I is something that wasn't even at all "fairly common". In PL/I, for any significant error, not only did you get a traceback in English, you also got line numbers for the error location and for the statements that called the procedure. I think that I also mentioned in a previous post in this thread that it was also possible to print values of PL/I variables along with the traceback. >> One published account (D. J. Kewley, "A Comparison between >> Pascal, FORTRAN, and PL/I", ACJ, Feb. 1981, pp 27-8) >> claimed that Pascal was faster than PL/I, >> and the author produced timing figures to "prove" it. >> The author failed to specify the PL/I option "REORDER" that would >> permit optimisation to take place. Furthermore, he compared >> one Pascal program performing complex arithmetic, with a PL/I >> program doing the same. Not supporting complex arithmetic, >> the Pascal program simulated those operations. When the PL/I >> version was rewritten using complex arithmetic, >> and with the REORDER option on the PROCEDURE statement, >> a 47% increase in speed was obtained. (see my refutation, ACJ, >> Aug. 1981, p. 107) > > (snip) > >> FORTRAN programmers tended to mimic FORTRAN style in >> their PL/I code that was inappropriate in PL/I. >> That caused PL/I programs to run slower than they should have. > > (snip) >>> In some cases you can do that, but it isn't so easy in a subroutine, >>> when the array might not be contiguous. > >> IIRC, in IBM's F-compiler, elements in arrays were contiguous, >> even in subroutines. [Even were that not so, a single loop suffices.] > > PL/I allows array cross sections that can be non-contiguous. The elements in a cross-section are contiguous for rows, but not for columns (in a matrix). However, the elements are separated from each other by a constant amount, so a single loop suffices (as you would expect, because only one subscript varies). > I believe some Fortran compilers now generate a test for a contiguous > array and then different code to process the two cases. As far as I > know, no PL/I compilers do that. (Then again, I haven't looked that > carefully.) >>> Also, since array operations were added to Fortran, they are one of >>> the biggest causes for complaints about slow programs. > > (snip) > >>> One reason is that people sometimes write array expressions that >>> require much more computation than they would written as loops. > >> That's their choice. > > That is true. Still, people seem to like doing it. > >>> PL/I only supports call-by-descriptor for arrays and strings. >>> That is good, but has more overhead. > >> Than what? Not having descriptors? >> Descriptors are necessary to deal with dynamic arrays. >> Without descriptors, it would be back to pre-Fortran 90, >> where only the address of the first element of an array was >> typically passed. > > The generated code to process assumed size arrays is often faster than > assumed shape. In many cases it is a worthwhile tradeoff on today's > machines. I think that you will find that there's little if any difference. > (snip) > >>>> [Considering what a rush job PL/I was, it's a remarkably good >>>> language. -John] > >>> I didn't know about that until recently when I bought "History >>> of Programming Languages", edited by Richard L. Wexelblat, which >>> covers the timeline for the PL/I language specification. (Writing >>> the actual compiler was a separate timeline.) > >>> As well as I can tell, it was October 1963 that the decision to >>> design a new language, instead of going to Fortran VI, was final, >>> and the group formed to write the specification. They were told >>> that it needed to be done by December 1963. In December, it was >>> extended to January 1964, and then slipped to February. > >> That those early dates slipped is irrelevant, as the S/360 wasn't >> even announced until 1964. In any case, a slippage by a few months >> was unimportant. > > From that description, they had four months. With the earlier > deadline, they would have had to have most of it done in two months. > For a language as complicated as PL/I, that isn't much time at all. Two months was probably expecting a bit much, but recall that I said that the decisions of what to include and omit would have already been made. I suspect that the work required at that time (October) would have been to decide on an appropriate syntax. > (snip) > >> [The code fron PL/I F was comparable to Fortran G, but much worse than >> Fortran H. The PL/I optimizing compiler's code was better, but still >> not as good as Fortran H and its descendants. -John] > > As long as you don't use too many fancy PL/I features, that should be > true. Of course you didn't have those features in Fortran IV. There is > a tendency to try out new features of a new language, though. > [I got some astonishingly awful code when I tried to use an array of > 12 bit fields. BIT strings usually need to be ALIGNED for best performance. [Didn't help -John] > As I recall, the code converted the fields to decimal > and back, for reasons I could not begin to guess. I can't imagine why that would have been done. The usual conversion for BIT strings is to BINARY. In point of fact, any conversion to arithmetic from BIT is to BINARY first, and them to any other type, if required. > Also, looking at the > manuals in Bitsavers, they were still adding features and > optimizations to PL/I F at least as late as 1968. -John] As IBM has been doing to their current Windows PL/I compiler.
[toc] | [prev] | [next] | [standalone]
| From | glen herrmannsfeldt <gah@ugcs.caltech.edu> |
|---|---|
| Date | 2012-05-05 05:20 +0000 |
| Subject | Re: PL/I code |
| Message-ID | <12-05-005@comp.compilers> |
| In reply to | #633 |
robin <robin51@dodo.com.au> wrote: (snip) >> There is, at least, more overhead in the procedure entry/exit >> sequence for recursive routines. > More overhead, maybe, but how much more? Registers usually have to be > saved, a return address has to be preserved somewhere. When the > machine has a stack, those things can go on the stack. There appears > to be no extra overhead. When the machine does not have a hardware > stack, one must be simulated, or, space must be made available for > saving those things, at each recursive call. In that case, a request > from the OS may need to be made for the storage. The request will add > to overhead. But again, how much extra? For the PDP-10/TOPS-10 Fortran, return addresses went on the stack, but local variables were still static, as usual for Fortran IV. OS/360 Fortran compilers use static storage for local variables and save areas (including the return address). No overhead for allocation. (snip) >> In the case of a local array, the compiler can make some optimizations >> that it can't make for a procedure argument. (snip) > In Fortran (90 or later), the descriptor holds, or can hold, > the stride value. Thus, a called procedure can access > non-contiguous elements in a single loop. (snip) >> PL/I allows array cross sections that can be non-contiguous. > The elements in a cross-section are contiguous for rows, > but not for columns (in a matrix). However, the elements are > separated from each other by a constant amount, so a single loop > suffices (as you would expect, because only one subscript varies). I suppose for a 2D array the elements will have a constant stride, but not for a higher D array. -- glen [That must be the new PDP-10 compiler. The old compiler, which looked a whole lot like OS/360 Fortran G, used JSA/JRA for subroutine calls, which saved the return address register in the first word of the subroutine. -John]
[toc] | [prev] | [next] | [standalone]
| From | glen herrmannsfeldt <gah@ugcs.caltech.edu> |
|---|---|
| Date | 2012-05-06 05:13 +0000 |
| Subject | Re: Fortran calls, was PL/I code |
| Message-ID | <12-05-006@comp.compilers> |
| In reply to | #634 |
(snip, I wrote) > For the PDP-10/TOPS-10 Fortran, return addresses went on the stack, > but local variables were still static, as usual for Fortran IV. > [That must be the new PDP-10 compiler. The old compiler, which looked > a whole lot like OS/360 Fortran G, used JSA/JRA for subroutine calls, > which saved the return address register in the first word of the > subroutine. -John] I remembered the PDP-8 using the "store the return address in the first word" method, but, yes, there was an earlier PDP-10 compiler. The one I used was, I believe, called Fortran-10 and the older one Fortran-40. (I am less sure about the latter, as I don't remember ever using it.) I did write some Fortran callable Macro-10 programs. -- glen [Yup, that's the one I used. -John]
[toc] | [prev] | [next] | [standalone]
| From | "robin" <robin51@dodo.com.au> |
|---|---|
| Date | 2012-05-09 10:46 +1000 |
| Subject | Re: Archaic hardware (was Fortran calls) |
| Message-ID | <12-05-009@comp.compilers> |
| In reply to | #635 |
From: "glen herrmannsfeldt" <gah@ugcs.caltech.edu> Sent: Sunday, 6 May 2012 3:13 PM > I remembered the PDP-8 using the "store the return address in the > first word" method, but, yes, there was an earlier PDP-10 compiler. > The one I used was, I believe, called Fortran-10 and the older one > Fortran-40. The CDC machines 7600, Cyber 70 series, etc used that method to store the return address. Surprising that those machines should take a step backwards, in view of around a decade of Algol (with recursion). It meant that each subroutine/function needed to implement its own stack should it be called recursively. Alan Turing designed the push-down pop-up stack for subroutines back in 1945, for his computer (later christened Automatic Computing Engine). That feature did not see hardware at that time. However, the Pilot ACE (1951) included a push-down stack (or, if you like) a queue. That push-down stack was continued into the DEUCE line (1955). The stack as a means of calling and returning from subroutines/ functions was implemented in the KDF9 (1961, delivered 1963). The S/360 and subsequent issue stored the return address in a register. That made it somewhat easier to have a universal stack manipulated by software.
[toc] | [prev] | [next] | [standalone]
| From | "robin" <robin51@dodo.com.au> |
|---|---|
| Date | 2012-09-19 11:04 +1000 |
| Subject | Re: PL/I nostalgia |
| Message-ID | <12-09-014@comp.compilers> |
| In reply to | #627 |
> [The code fron PL/I F was comparablw to Fortran G, but much worse than
> Fortran H. The PL/I optimizing compiler's code was better, but still
> not as good as Fortran H and its descendants. -John]
Finally I have to hand Tucker's "Programming Languages".
Case study 2, matrix inversion with 20 x 20 data:
with IBM 370-145 FORTRAN (G) execution time 8.41 secs
(H) execution time 5.28 secs.
With IBM 370-145 PL/I (F) execution time 6.31 secs
PL/I Optimiser execution time 5.77 secs.
(refer to pages 112 and 279 for times)
However, in the case of the PL/I program, Tucker //omitted// to supply
the option (REORDER) which is necessary to obtain full optimisation.
Thus, the PL/I optimiser execution obtained was larger than it should
have been.
It is clear that the times for FORTRAN (G) and PL/I(F) are equivalent,
and that FORTRAN(H) and PL/I optimiser times are equivalent.
As well as that, FORTRAN (H) required c. 150K of memory (i.e. a 256K
machine) which was far more than the 128K that we had initially,
whereas PL/I (F) required only 64K and IIRC FORTRAN (G) a little more.
[toc] | [prev] | [next] | [standalone]
| From | glen herrmannsfeldt <gah@ugcs.caltech.edu> |
|---|---|
| Date | 2012-09-19 03:56 +0000 |
| Subject | Re: PL/I nostalgia |
| Message-ID | <12-09-015@comp.compilers> |
| In reply to | #750 |
robin <robin51@dodo.com.au> wrote: >> [The code fron PL/I F was comparablw to Fortran G, but much worse than >> Fortran H. The PL/I optimizing compiler's code was better, but still >> not as good as Fortran H and its descendants. -John] Well, the dynamically allocated variables and save areas for PL/I are naturally slower than static allocated Fortran IV. Also, many PL/I features naturally don't optimize as well as Fortran. > Finally I have to hand Tucker's "Programming Languages". I have one of those. Not my favorite, but not bad. "History of Programming Languages" is better. > Case study 2, matrix inversion with 20 x 20 data: What page is that on? > with IBM 370-145 FORTRAN (G) execution time 8.41 secs > (H) execution time 5.28 secs. > With IBM 370-145 PL/I (F) execution time 6.31 secs > PL/I Optimiser execution time 5.77 secs. > (refer to pages 112 and 279 for times) Not in the second edition. > However, in the case of the PL/I program, Tucker //omitted// to supply > the option (REORDER) which is necessary to obtain full optimisation. > Thus, the PL/I optimiser execution obtained was larger than it should > have been. When did that appear? I don't remember it in (F). > It is clear that the times for FORTRAN (G) and PL/I(F) are equivalent, > and that FORTRAN(H) and PL/I optimiser times are equivalent. I suppose. A better test would use a larger matrix, though. > As well as that, FORTRAN (H) required c. 150K of memory (i.e. a 256K > machine) which was far more than the 128K that we had initially, > whereas PL/I (F) required only 64K and IIRC FORTRAN (G) a little more. If you really want to be fair, add the compilation time to the run time, then see which one is faster. -- glen
[toc] | [prev] | [next] | [standalone]
| From | "robin" <robin51@dodo.com.au> |
|---|---|
| Date | 2012-09-21 13:53 +1000 |
| Subject | Re: PL/I nostalgia |
| Message-ID | <12-09-016@comp.compilers> |
| In reply to | #751 |
From: "glen herrmannsfeldt" <gah@ugcs.caltech.edu> Sent: Wednesday, 19 September 2012 1:56 PM > robin <robin51@dodo.com.au> wrote: >>> [The code fron PL/I F was comparablw to Fortran G, but much worse than >>> Fortran H. The PL/I optimizing compiler's code was better, but still >>> not as good as Fortran H and its descendants. -John] > > Well, the dynamically allocated variables and save areas for PL/I are > naturally slower than static allocated Fortran IV. But not where it counts. By the time some procedure (such as INVERT) is called, the array(s) has(have) been allocated. Allocation is a once-off task, probably not measurable in terms of time. And the FORTRAN IV code was, essentially, rigid, and required re-compilation for larger arrays. > Also, many PL/I features naturally don't optimize as well as Fortran. That may be so, but to have to re-compile the FORTRAN code to deal with larger-sized arrays counted strongly against it. As well, PL/I offered full roll-out of fixed-size array operations Not all arrays needed to be dynamic. As well as that, PL/I offered such things as double precision complex, string-handling, and error recovery. Error recovery more than compensated for any difference in speed that may have existed between FORTRAN and PL/I. Having to re-run FORTRAN code because of some error to find out what went wrong outweighed any speed advantage that FORTRAN might have had, because in PL/I, the error information was already there (including values of variables), and without necessarily a program termination. Hence, a re-run of the PL/I code was avoided. That was important, not only in terms of machine time, but also in terms of turn-around time, because turn-around time in those days was as much as a week. > Finally I have to hand Tucker's "Programming Languages". > > I have one of those. Not my favorite, but not bad. > "History of Programming Languages" is better. > >> Case study 2, matrix inversion with 20 x 20 data: > > What page is that on? Look in the index. >> with IBM 370-145 FORTRAN (G) execution time 8.41 secs >> (H) execution time 5.28 secs. > >> With IBM 370-145 PL/I (F) execution time 6.31 secs >> PL/I Optimiser execution time 5.77 secs. > >> (refer to pages 112 and 279 for times) > > Not in the second edition. >> However, in the case of the PL/I program, Tucker //omitted// to supply >> the option (REORDER) which is necessary to obtain full optimisation. >> Thus, the PL/I optimiser execution obtained was larger than it should >> have been. > > When did that appear? I don't remember it in (F). It wasn't in F, but it was in the optimising compiler, where it counted. >> It is clear that the times for FORTRAN (G) and PL/I(F) are equivalent, >> and that FORTRAN(H) and PL/I optimiser times are equivalent. > > I suppose. A better test would use a larger matrix, though. 20 W 20 is more than large enough. It's the size of a typical matrix in a typical job. >> As well as that, FORTRAN (H) required c. 150K of memory (i.e. a 256K >> machine) which was far more than the 128K that we had initially, >> whereas PL/I (F) required only 64K and IIRC FORTRAN (G) a little more. > > If you really want to be fair, add the compilation time to the > run time, then see which one is faster. Compilation time is only relevant when the run-time is very short. When speed mattered, it was in long-running executable codes, in which case, compilation time was unimportant. To get the entire time for a job, you'd have to add in the link time, which Tucker didn't provide. And if compilation time was important, such as in short jobs, you'd have used PL/C or WATFOR.
[toc] | [prev] | [next] | [standalone]
| From | glen herrmannsfeldt <gah@ugcs.caltech.edu> |
|---|---|
| Date | 2012-09-21 07:00 +0000 |
| Subject | Re: PL/I nostalgia |
| Message-ID | <12-09-017@comp.compilers> |
| In reply to | #752 |
robin <robin51@dodo.com.au> wrote: > From: "glen herrmannsfeldt" <gah@ugcs.caltech.edu> > Sent: Wednesday, 19 September 2012 1:56 PM >> robin <robin51@dodo.com.au> wrote: >>>> [The code fron PL/I F was comparablw to Fortran G, but much worse than >>>> Fortran H. The PL/I optimizing compiler's code was better, but still >>>> not as good as Fortran H and its descendants. -John] >> Well, the dynamically allocated variables and save areas for PL/I are >> naturally slower than static allocated Fortran IV. > But not where it counts. By the time some procedure (such as INVERT) > is called, the array(s) has(have) been allocated. Allocation is a > once-off task, probably not measurable in terms of time. That comment was before the matrix inversion discussion, and is meant more generally. Yes, if you are careful with your allocations, and minimize subroutine calls, then it isn't so bad. Current coding practices encourage more and smaller procedures than were usual in the early PL/I days. > And the FORTRAN IV code was, essentially, rigid, and required > re-compilation for larger arrays. For single task systems, most often the memory wouldn't be used for anything else, but, yes, it is convenient to dynamically allocate to the appropriate size. It is especially useful for multitasking systems. >> Also, many PL/I features naturally don't optimize as well as Fortran. > That may be so, but to have to re-compile the FORTRAN code to deal > with larger-sized arrays counted strongly against it. As well, PL/I > offered full roll-out of fixed-size array operations Not all arrays > needed to be dynamic. As well as that, PL/I offered such things as > double precision complex, string-handling, and error recovery. IBM Fortran has had COMPLEX*16 about as far back as PL/I, but most others didn't. (Though the most common use for COMPLEX, the FFT, is most often written using REAL arrays.) Compilers I know of have the overhead needed for RECURSIVE, even when the attribute isn't used. But again, minimize the number of procedure calls and it isn't so bad. > Error recovery more than compensated for any difference in speed that > may have existed between FORTRAN and PL/I. Having to re-run FORTRAN > code because of some error to find out what went wrong outweighed any > speed advantage that FORTRAN might have had, because in PL/I, the > error information was already there (including values of variables), > and without necessarily a program termination. Hence, a re-run of the > PL/I code was avoided. Pretty program dependent, but, yes, PL/I can make it easier. On the other hand, keeping track of ON units through procedure calls is another increase in the time needed for a call. > That was important, not only in terms of > machine time, but also in terms of turn-around time, because > turn-around time in those days was as much as a week. >> Finally I have to hand Tucker's "Programming Languages". >> I have one of those. Not my favorite, but not bad. >> "History of Programming Languages" is better. >>> Case study 2, matrix inversion with 20 x 20 data: >> What page is that on? > Look in the index. Might have gone away for the 2nd edition. (snip) > 20 W 20 is more than large enough. > It's the size of a typical matrix in a typical job. Pretty small for many problems, but then most bigger than that should be done in ways other than inversion, such as LU decomposition. -- glen [Even in single task systems, dynamic allocation is useful since it means that variables only take up space when a routine is active. The Fortran version of that was overlays, which were a lot klunkier. -John]
[toc] | [prev] | [next] | [standalone]
| From | "robin" <robin51@dodo.com.au> |
|---|---|
| Date | 2012-09-30 10:45 +1000 |
| Subject | Re: PL/I nostalgia |
| Message-ID | <12-09-022@comp.compilers> |
| In reply to | #753 |
From: "glen herrmannsfeldt" <gah@ugcs.caltech.edu> Sent: Friday, 21 September 2012 5:00 PM > robin <robin51@dodo.com.au> wrote: >> From: "glen herrmannsfeldt" <gah@ugcs.caltech.edu> >> Sent: Wednesday, 19 September 2012 1:56 PM > >>> Well, the dynamically allocated variables and save areas for PL/I are >>> naturally slower than static allocated Fortran IV. > >> But not where it counts. By the time some procedure (such as INVERT) >> is called, the array(s) has(have) been allocated. Allocation is a >> once-off task, probably not measurable in terms of time. > > That comment was before the matrix inversion discussion, > and is meant more generally. So was my comment (in general terms). See "some procedure". > Yes, if you are careful with your allocations, and minimize > subroutine calls, then it isn't so bad. > > Current coding practices encourage more and smaller procedures > than were usual in the early PL/I days. > >> And the FORTRAN IV code was, essentially, rigid, and required >> re-compilation for larger arrays. > > For single task systems, most often the memory wouldn't be used > for anything else, but, yes, it is convenient to dynamically > allocate to the appropriate size. It is especially useful > for multitasking systems. It is essential for multitasking systems because having unused array space in a program meant that other programs could not be loaded -- thus slowing down throughput. As for single-task systems, it's important also, because unwanted memory (array space) in a PL/I program could be freed during execution, thus allowing (an)other array(s) to be allocated. Re-compiling a FORTRAN program just to make an array size larger was wasteful. >>> Also, many PL/I features naturally don't optimize as well as Fortran. > >> That may be so, but to have to re-compile the FORTRAN code to deal >> with larger-sized arrays counted strongly against it. As well, PL/I >> offered full roll-out of fixed-size array operations. Not all arrays >> needed to be dynamic. As well as that, PL/I offered such things as >> double precision complex, string-handling, and error recovery. > > IBM Fortran has had COMPLEX*16 about as far back as PL/I, but most > others didn't. (Though the most common use for COMPLEX, the FFT, > is most often written using REAL arrays.) > > Compilers I know of have the overhead needed for RECURSIVE, even > when the attribute isn't used. But again, minimize the number > of procedure calls and it isn't so bad. You wouldn't notice the time unless the procedure reference were in a loop being ecxecuted thousands of times. >> Error recovery more than compensated for any difference in speed that >> may have existed between FORTRAN and PL/I. Having to re-run FORTRAN >> code because of some error to find out what went wrong outweighed any >> speed advantage that FORTRAN might have had, because in PL/I, the >> error information was already there (including values of variables), >> and without necessarily a program termination. Hence, a re-run of the >> PL/I code was avoided. > > Pretty program dependent, but, yes, PL/I can make it easier. It made it hugely easier, for turnaround time was around a week in those times. > On the other hand, keeping track of ON units through procedure > calls is another increase in the time needed for a call. Again, unless the procedure is in a loop that is executed thousands of times, you wouldn't notice the time. >> That was important, not only in terms of >> machine time, but also in terms of turn-around time, because >> turn-around time in those days was as much as a week. > >> 20 W 20 is more than large enough. >> It's the size of a typical matrix in a typical job. > > Pretty small for many problems, but then most bigger than > that should be done in ways other than inversion, such > as LU decomposition. It was common then to use larger array sizes with matrix inversion. The 20 x 20 matrix was a reasonable size for the timing test. > [Even in single task systems, dynamic allocation is useful > since it means that variables only take up space when a > routine is active. The Fortran version of that was overlays, > which were a lot klunkier. -John] Agreed. One large job (multiple regression) was able to run in PL/I under PCP by organising various sections as BEGIN-END blocks, so as each section completed, the storage was freed, making it possible to enter the following section which required additional array storage. Without that, the program couldn't run. And while on the topic of running large programs in small memories: an array of small integers was easily accommodated: Instead of using BINARY, I chose FIXED DECIMAL (1). That used one-quarter of the space compared to a 32-bit FORTRAN integer word, and one-half the space of a default binary integer in PL/I. PL/I on the /360 also permitted 16-bit signed binary integers, and these could be used for large arrays with a saving of 50% over the FORTRAN integer. [Unless someone has something to add that is more directly related to compiler design, here endeth the skirmishing. -John]
[toc] | [prev] | [standalone]
Back to top | Article view | comp.compilers
csiph-web