Compare the Performance and Effectiveness of the Obtained Executables
The goal of this task is to understand the impact of IEEE-compliant compilation on performance and RESULT! These codes provided have been written in a way to demonstrate weird things one may encounter with the IEEE Floating Point Arithmetic.
1. Go to the subdirectory /exe_ieee
$ cd .. $ cd exe_ieee
which contains the following files:
$ ls prog1.f # average of 2 numbers (using division) prog2.f # average of 3 numbers (using division) prog3.f # average of 3 numbers (using multiplication with 0.333..) Makefile
Programs are compiled with the use of a Makefile (you will see many of these in future labs so look at it carefully -wise thing to ALWAYS do with all Makefiles:
$ cat Makefile # This directive is used to tell "make" that the clean and all targets # are not real files .PHONY: clean all # Select the compiler by commenting and decommenting each line #FC = gfortran FC = ifort #FC = pgf90 # Here we define a variable that contains all the executables we would like to build TARGETS = prog1_O0 prog1 prog1_O3 prog2_O0 prog2_O0 prog2 prog2_O3 prog3_O3 prog2_O3_unsafe_math # This is a "catch-all" target: $(TARGETS) means: "value of the # TARGETS variable" # Since the first target is the one executed by default, typing "make # all" is the same, in this context, as typing just "make" all: $(TARGETS) # This is a typical make rule, it can be interpreted as: # "'prog1.f' is required to build 'prog1_O0' # (first line: target: requirements) # To build prog1_O0, do this: '$(FC) -o prog1_O0 -O0 prog1.f' # (second line. $@ get expanded to prog1_O0) prog1_O0: prog1.f $(FC) -o $@ -O0 prog1.f prog1: prog1.f $(FC) -o $@ prog1.f prog1_O3: prog1.f $(FC) -o $@ -O3 prog1.f prog2_O0: prog2.f $(FC) -o $@ -O0 prog2.f prog2_O1: prog2.f $(FC) -o $@ -O1 prog2.f prog2: prog2.f $(FC) -o $@ prog2.f prog2_O3: prog2.f $(FC) -o $@ -O3 prog2.f # The -funsafe-math-optimizations flag is not supported by the PGI # compiler. Ignore the error at the end of the PGI compilation prog2_O3_unsafe_math: prog2.f $(FC) -o $@ -O3 -funsafe-math-optimizations prog2.f prog3_O3: prog3.f $(FC) -o $@ -O3 prog3.f # this target has no requirements: each time make it's invoked as "make clean" # it will remove the old executabes if any clean: /bin/rm -f $(TARGETS)
(Q. what do each of the options do???)
2. Look at the first program, prog1.f,: we calculate a two-point average, requiring a division by 2. Make prog1 and measure the runtime.
$ make prog1 $ /usr/bin/time ./prog1
You should obtain something similar to this:
0.04user 0.00system 0:00.04elapsed 97%CPU (0avgtext+0avgdata 0maxresident)k 0inputs+0outputs (0major+276minor)pagefaults 0swaps
3. Now we take the second program, prog2.f, calculating a three-point average, requiring a division by 3. Make prog2 and measure the runtime as compared with prog1 (Hint: you can get all executables at once just typing "make")
4. How do the runtimes compare? Does the extra addition justify the increase in CPU time?
(Hint: think NO, but KNOW why) (Hint2: if you are not sure, modify prog2 replacing the division by 3 with a division by 2 in order to be certain that it's not a matter of addends number.)
5. Look at the prog3.f: where is the difference between prog2 and prog3 ? Make it and measure runtime
6. Make now prog2_O3 and take note of the extra compiler option used. What does it do?
(Hint:
$ man gfortran
for details)
7. Measure the runtime of prog2_O3. Compare with prog3 and even with prog1
8. Modify prog2 and prog3 in order to print out the final average: are they equal ?
9. Repeat all the above with another fortran compiler(intel/pgi) and identify the flags for those compiler that play the same role of -funsafe-math-optimizations for gfortran compiler (unless it is the default, in which case search for the "ieee safe math" option). Hint: try: ifort -help | more or pgf90 -help | more
to get a list of available options and a short description.