|
Prev: Text_IO from a stream
Next: ANN: Some updates
From: Eric Hughes on 30 Mar 2008 13:12 On Mar 29, 7:51 am, kongra <kon...(a)gmail.com> wrote: > Start_T := Ada.Real_Time.Clock; > for K in 1 .. 10 loop > for I in 1 .. 10_000_000 loop > Val := Val + I; > end loop; > end loop; > End_T := Ada.Real_Time.Clock; I have a question about this piece of the program. Because the middle uses only variables 'K', 'I', and 'Val', and the side-effects of modifying these variables are entirely local, and because there's no inter-dependency of these variables upon either the first or last statements, aren't the following reorderings legal for code generation? To wit: Long_Statement ; Start_T := Ada.Real_Time.Clock ; End_T := Ada.Real_Time.Clock ; Start_T := Ada.Real_Time.Clock ; End_T := Ada.Real_Time.Clock ; Long_Statement ; Irrelevant to the quirks mentioned earlier, isn't it legal operation for the interval to come out zero? It seems that for known-correct operation for all possible compilers you'd need to manually serialize these operations in the order desired. Eric
From: Robert A Duff on 30 Mar 2008 14:59 Eric Hughes <eric.eh9(a)gmail.com> writes: > On Mar 29, 7:51 am, kongra <kon...(a)gmail.com> wrote: >> Start_T := Ada.Real_Time.Clock; >> for K in 1 .. 10 loop >> for I in 1 .. 10_000_000 loop >> Val := Val + I; >> end loop; >> end loop; >> End_T := Ada.Real_Time.Clock; > > I have a question about this piece of the program. Because the middle > uses only variables 'K', 'I', and 'Val', and the side-effects of > modifying these variables are entirely local, and because there's no > inter-dependency of these variables upon either the first or last > statements, aren't the following reorderings legal for code > generation? To wit: > > Long_Statement ; > Start_T := Ada.Real_Time.Clock ; > End_T := Ada.Real_Time.Clock ; > > Start_T := Ada.Real_Time.Clock ; > End_T := Ada.Real_Time.Clock ; > Long_Statement ; > > Irrelevant to the quirks mentioned earlier, isn't it legal operation > for the interval to come out zero? Yes. For example, I can calculate the final value of Val with pencil and paper, so I guess I could teach an optimizer to do it at compile time. ;-) >...It seems that for known-correct > operation for all possible compilers you'd need to manually serialize > these operations in the order desired. The only thing that's guaranteed is I/O behavior, so you have to do some I/O. And you should inspect the generated machine code to see if you're measuring what you think you're measuring. In other words, this sort of thing is pretty much outside the language definition. Also, it might be better to measure using outside tools, like the Unix 'time' command, or perhaps a stopwatch. - Bob
From: Eric Hughes on 30 Mar 2008 17:12 On Mar 30, 12:59 pm, Robert A Duff <bobd...(a)shell01.TheWorld.com> wrote: > The only thing that's guaranteed is I/O behavior, so you have to do some > I/O. Only? You can also count on task termination, no? Example code below. Eric with Ada.Real_Time ; with Ada.Text_IO ; procedure Foo is Val : Natural := 0 ; Start_T, End_T : Ada.Real_Time.Time ; use Ada.Real_Time ; begin declare task Start_Timer ; task body Start_Timer is begin Start_T := Ada.Real_Time.Clock ; end ; begin null ; end ; declare task Compute ; task body Compute is begin for K in 1 .. 10 loop for I in 1 .. 10_000 loop Val := Val + I * I ; end loop; end loop; end ; begin null ; end ; declare task End_Timer ; task body End_Timer is begin End_T := Ada.Real_Time.Clock ; end ; begin null ; end ; Ada.Text_IO.Put_Line( Natural'Image( Val ) ) ; Ada.Text_IO.Put_Line( Duration'Image( To_Duration( End_T - Start_T ) ) ) ; end Foo ;
From: Robert A Duff on 30 Mar 2008 17:28 Eric Hughes <eric.eh9(a)gmail.com> writes: > On Mar 30, 12:59 pm, Robert A Duff <bobd...(a)shell01.TheWorld.com> > wrote: >> The only thing that's guaranteed is I/O behavior, so you have to do some >> I/O. > > Only? You can also count on task termination, no? Insofar as it affects I/O, yes. And I suppose you can count on termination of the program as a whole (that is, if all tasks terminate, then so should the program). >...Example code > below. > > Eric > > > with Ada.Real_Time ; > with Ada.Text_IO ; > procedure Foo > is > Val : Natural := 0 ; Better make that modular, or this conversion gets confused by the overflow issue. Oh, never mind, I see you reduced the counts, and (if I can do that in my head correctly) it won't overflow. ;-) > Start_T, End_T : Ada.Real_Time.Time ; > use Ada.Real_Time ; > begin > declare > task Start_Timer ; > task body Start_Timer is begin > Start_T := Ada.Real_Time.Clock ; > end ; > begin > null ; > end ; > > declare > task Compute ; > task body Compute is begin > for K in 1 .. 10 loop > for I in 1 .. 10_000 loop > Val := Val + I * I ; > end loop; > end loop; > end ; > begin > null ; > end ; > > declare > task End_Timer ; > task body End_Timer is begin > End_T := Ada.Real_Time.Clock ; > end ; > begin > null ; > end ; > > Ada.Text_IO.Put_Line( Natural'Image( Val ) ) ; > Ada.Text_IO.Put_Line( Duration'Image( To_Duration( End_T - > Start_T ) ) ) ; > > end Foo ; I don't see any language rule that would prevent moving the calculation of Val before or after the Start_Timer or End_Timer tasks, since they don't use that value. Or in parallel with them. Or at compile time. I'm not claiming that real compilers do these transformations in practise, nor implying that they "should". I suppose you could reasonably argue that the Clock in Start_Timer must happen before the one in End_Timer (since a calculation based on those values is printed out). So I guess it would be wrong to print a negative time span. Meaningful benchmarking is hard! ;-) - Bob
|
Pages: 1 Prev: Text_IO from a stream Next: ANN: Some updates |