1 / 25

Compiler Techniques for Single Processor Tuning

Compiler Techniques for Single Processor Tuning. An introduction. Outline. Compiler is the primary tool of computer program optimization: structure of the compiler and the compilation process compiler optimizations steering of the compilation process - compiler options

Download Presentation

Compiler Techniques for Single Processor Tuning

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Compiler Techniques for Single Processor Tuning An introduction

  2. Outline • Compiler is the primary tool of computer program optimization: • structure of the compiler and the compilation process • compiler optimizations • steering of the compilation process - compiler options • structure of the run time libraries and scientific libraries • computational domain and computation accuracy

  3. The Compiler • Solving: • data dependencies • control flow dependencies • parallelization • compactification of code • optimal scheduling of the code Compilation process Intermediate representation • Compiler manages processor resources: • registers • integer/floating-point execution units • load/store/prefetch for data flow in/out of processor • The implementation details of processor and system architecture are build into the compiler • User Program (C/C++/Fortran, etc.) • high level representation • low level representation • Machine instructions

  4. MIPSpro Compiler Components source Executable object Inter- Procedural Analyser Linker F77/f90 cc/CC driver Global optimizer Code generator Front-end (source to WHIRL format) Macro pre- processor Inter- Procedural Analyser Loop nest optimizer Parallel optimizer • There are no source-to-source optimizers or parallelizers • source code is translated to WHIRL (Winning Hierarchical Intermediate Representation Language); • same IR for different levels of representation • whirl2f and whirl2c translates back into Fortran or C from IRs • Inter-Procedural analyser requires final translation at link time

  5. Compiler Optimizations • Global optimizer: • dead code elimination • copy propagation • loop normalisation • stride one loops • single induction variable • memory alias analysis • strength reduction • Inter-Procedural Analyser: • cross-file function inlining • dead function elimination • dead variable elimination • padding of variables in common blocks • inter-procedural constant propagation • Automatic parallelizer • loop level work distribution • Loop Nest optimizer: • loop unrolling (outer) • loop interchange • loop fusion/fission • loop blocking • memory prefetch • padding local variables • Code Generator: • software pipelining • inner loop unrolling • if-conversion • read/write optimization • recurrence breaking • instruction scheduling inside basic blocks

  6. SGI Architecture, ABI, Languages • Instruction Set Architecture (ISA): • -mips4 (R1x000, R8000, R5000 processors) • -mips3 (R4400) • -mips[1|2] (R3000, R4000 processors, invokes old ucode compiler) • ABI (Application Binary Interface): • -n32 (32 bit pointers, 4 byte integers, 4 byte real) • -64 (64 bit pointers, 4 byte integers, 4 byte real) • Languages: • C • C++ • Fortran 77 • Fortran 90 Variable C size[bit] F size[bit] -n32 -64 -n32 -64 char/character 8 8 8 8 short 16 16 int/integer 32 32 32 32 long 32 64 long long 64 64 logical 32 32 float/real 32 32 32 32 double 64 64 64 64 pointer 32 64

  7. Options: ABI & ISA • Option Functionality • -n32 invoke the MIPSpro Compiler, use 32 bit addressing • -64 invoke the MIPSpro Compiler, use 64 bit addressing • -o32/-32 invoke the old ucode compiler, 32 bit addressing • -mips[1234] ISA; -mips[12] implies ucode compiler • There are two more ways to define the ABI and ISA: • environment variable “SGI_ABI” can be set to -n32 or -64 • the ABI/ISA/Processor/optimization can be set in a file ~/compiler.defaults or /etc/compiler.defaults. In addition, the location of the file can be defined by “COMPILER_DEFAULTS_PATH” environment variable. The file should contain a line like: -DEFAULT:abi=n32:isa=mips4:proc=r10000:arith=3:opt=O3 • There is a way to find which compiler flags were used: • dwarfdump -i file.o | grep DW_AT_producer

  8. Optimization Levels • Compilation speed degrades with higher optimization • -O0 turn off all optimizations • -O1 only local optimizations • -O2 or -O extensive but conservative optimizations • -O3 aggressive optimizations, LNO, software pipelining • -ipa inter-procedural analysis (only at -O2 and -O3) • -apo automatic parallelization option (same as -pfa) • -g[0|3]debugging switch: -g0 forces -O0-g3 to debug with -O3

  9. Options: Performance • Option Functionality • -r10000 Generate optimal instruction schedule for the R10000 proc • -r8000 Generate optimal instruction schedule for the R8000 proc • -O[0|1|2|3] Set optimization Level to 0, 1, 2, 3 • -Ofast=[ipXX] Select best optimization for the given architecture • -mp Enable multi-processing directives • -mpio Support I/O from a parallel region • -apo Invoke automatic parallelization option XX machine (output of thehinv -c processorcommand) 27 Origin2000 (all cpu frequencies and cache sizes) 35 Origin3000 (all cpu frequencies and cache sizes) optimizations may differ on the version of the compiler. Currently: -O3 -IPA-TARG:platform=ip27 -n32 -OPT:Olimit=0:roundoff=3:div_split=ON:alias=typed (thus -Ofast switch invokes the Interprocedural Analyser)

  10. Options: Porting • Option Functionality • -d8/d16 Double precision variables as 8 or 16 bytes • -r8 Convert REAL to REAL*8 and COMPLEX to COMPLEX*16 (1) • -i8 Convert INTEGER to INTEGER*8 and LOGICAL to 8 byte sizes (1) • -static Local variables will be initialised in fixed locations on the heap • -col[72|120] Source line is 72 or 120 columns • -Dname Define name for the pre-processor • -Idir Define include directory dir • -alignN Assume alignment on the N=8,16,32,64,128 bit boundary • -version Show compiler version • -show Put the compiler in verbose mode: all switches are displayed • (1) Note: explicit sizes are preserved, i.e. REAL*4 remains 32 bit

  11. Options: Debugging • Option Functionality • -g Disable optimization and keep all symbol tables • -DEBUG: the DEBUG group option (man DEBUG_GROUP): • check_div=nn=1 (default) check integer divide by zero • n=2 check integer overflow • n=3 check integer divide by zero and overflow • subscript_check (default ON) to check for subscripts out of range • C/C++: produces trap #8 • f77: aborts run and dumps core • f90: aborts run if setenv F90_BOUNDS_CHECK_ABORT • verbose_runtime (default OFF) to give source line number of failures • trap_uninitialized (default OFF) initialise all variables to 0xFFFA5A5 • when used as pointer - access violation • when used as fp values - NaN causes fp trap • Example: • f77 -n32 -mips4 -g file.f \ • -DEBUG:subscript_check:verbose_runtime=ON \ • -DEBUG:check_div=3 -DEBUG:trap_uninitialized=ON

  12. Compilation Examples • 1. Produce executable a.out with default compilation options: f77 source.f • cc source.f • be aware of the defaults setting (e.g./etc/compiler.defaults) • same flags for Fortran and C • 2. Options for debugging: • f77/cc -o prog -n32 -g -static source.f • 2. Explicit setting of ABI/ISA/Processor, highest opt:f77/cc -o prog -n32 -mips4 -r10000 -O3 source.f • 3. Detailed control of the optimization process with the • group options : • f77/cc -o prog -64 -mips4 -O3 -Ofast=ip27 • -OPT:round=3:IEEE_arith=3 -IPA:dfe=on ...

  13. Fine Tuning Compiler Actions Compiler performs many sophisticated optimizations on the source code under certain assumption about the program. Typically: • program data is large (does not fit into the cache) • program does not violate language standard • program is insensitive to roundoff errors • all data in the program is alias-ed, unless it can prove otherwise if one or more of these assumptions does not hold, compiler should be tuned to the program with the compiler options. Most important: • OPT for general optimizations assumptions • LNO for the Loop Nest optimizer options • IPA for the Inter-Procedural Analyser options • Additional options that help to tune the compiler properly: • TENV, TARG for the target machine and environment description • LIST, DEBUG for the listing and debugging options

  14. Group Options • Compiler options can be set with the key=value expressions on the command line. These options are combined in logical groups. Multiple key=val expressions are colon separated; same group headings can be specified several times, the effects are cumulative: • E.g.: -OPT:roundoff=2:alias=restrict -OPT:IEEE_arithmetic=3 etc. • Group Heading Reference page Usage comments • -OPT:key=val cc(1) f77(1) opt(5) optimizations • -TENV:key=val cc(1) f77(1) Control target environment • -TARG:key=val cc(1) f77(1) Control target architecture • -FLIST/CLIST cc(1) f77(1) Listing control • -LIST:key=val cc(1) f77(1) Options to control listing • -DEBUG:key=val debug_group(5) Debugging options • -IPA:key=val ipa(5) Inter-Procedural Analyser control • -INLINE:key=val ipa(5) Procedure inliner control • -LNO:key=val lno(5) Loop Nest optimizer control • -MP:key=val cc(1) f77(1) parallelization control • -LANG: cc(1) f77(1) language compatibility features

  15. Compiler man Pages • Primary man pages: • man f77(1) f90(1) cc(1) CC(1) ld(1) • some of the compiler option groups are rather large and deserve their own man pages • man opt(5) • man lno(5) • man ipa(5) • man DEBUG_GROUP(5) • man mp(3F) • man pe_environ(5) • man sigfpe(3C)

  16. The Run-Time Library Structure *.a, *.so ucode-compiler nonshared/*.a *.a, *.so *.a, *.so Cmplrs/mongoose-compiler Cmplrs/mongoose-compiler nonshared/*.a nonshared/*.a *.a, *.so *.a, *.so nonshared/*.a nonshared/*.a *.a, *.so *.a, *.so mips3 mips3 nonshared/*.a nonshared/*.a mips4 mips4 o32 lib/ n32 lib32/ /usr lib64/ n64 Environment variables: LD_LIBRARY_PATH LD_LIBRARY32_PATH LD_LIBRARY64_PATH

  17. The Scientific Libraries • Standard scientific libraries containing: • Basic Linear Algebra operations and algorithms: • BLAS1, BLAS2, BLAS3 (see man intro_blas1,_blas2,_blas3) • LAPACK (see man intro_lapack) • Fast Fourier Transformations (FFT): • 1D, 2D, 3D, multiple 1D transformations (see man intro_fft) • Convolutions (Signal Processing, e.g. man SIIR2D) • Sparse Solvers (see man solvers; man PSLDLT) • To use: • -lscs serial versions • -lscs_mp-mp for parallel versions • man intro_scsl for detailed description • -lcomplib.sgimath or -lcomplib.sgimath_mp for older versions • man complib.sgimath for detailed desctiption

  18. Computational Domain • Range of numbers (from /usr/include/limits.h): • FLT_DIG 6 /* decimal digits of precision of a float */ • FLT_MAX 3.40282347E+38F • FLT_MIN 1.17549435E-38F • DBL_DIG 15 /* decimal digits of precision of a double */ • DBL_MAX 1.7976931348623157E+308 • DBL_MIN 2.2250738585072014E-308 • LONGLONG_MIN -9223372036854775807LL-1LL • LONGLONG_MAX 9223372036854775807LL • ULONGLONG_MAX 18446744073709551615LLU • The extended precision (REAL*16) is available and supported by the compiler. But this mode of calculation is slow (by factor ~40)

  19. Underflow and Denormal Numbers • When de-normalised numbers emerge in a computation (i.e. numbers x<DBL_MIN) they are flushed to zero by default: • will print zero. To force IEEE-754 gradual underflow it is necessary to manipulate status register on the R1x000 cpu. • Calling no_flush at the beginning of the program will print • 0.22250738585072014D-308 • Flush-to-zero property can lead to x-y=0, while xy . • Keeping de-normalised numbers in computations will avoid that condition, but will cause • fp exception, that must be processed in software. • It is a performance issue - not to manipulate the de-normalized numbers in calculations. #include <sys/fpu.h> void no_flush_() { union fpc_csr f; f.fc_word = get_fpc_csr(); f.fc_struct.flush = 0; set_fpc_csr(f.fc_word); } Program denorm real*8 a,b a = 2.2250738585072014D-308 b = a/10.0D0 write(6,10) b end

  20. Overflow Example Flush to zero! • Program example that generates overflows and underflows: • Output with all exceptions ignored by default: • setenv TRAP_FPE „UNDERFL=TRACE; OVERFL=TRACE“ • will trap at Overflow and Underflow and produce traceback (Link-lfpe). Parameter (N=20) INCLUDE “/usr/include/limits.h” Real*8 A(N),B(N) complex*16 C(N) do I=1,N A(I) = (FLT_MAX/10)*I ! single precision range B(I) = (FLT_MIN*10)/I ! will fit into double enddo C = CMPLX(A,B) ! Standard requires passing from base precision: real*4 ! write (0,’(I3,2(2G22.15/))’) (I,A(I),B(I),C(I),I=1,N) Compile with: f77 -n32 -mips4 -O3 Note: Compilation with -r8 avoids the error. 10 0.340282347000000E+39 0.117549435000000E-37 A,B 0.340282346638529E+39 0.117549435082229E-37 Cr,Ci 11 0.374310581700000E+39 0.106863122727273E-37 Infinity 0.000000000000000 12 etc… Overflow!

  21. Floating Point Exceptions • A fp status register flag is set when fpu is has an illegal condition: • division by zero • overflow • underflow • invalid • inexact • By default, all exceptions are ignored! • (e.g. for 1/0 NaN value is set and execution continues) • The status register can be programmed to raise a Floating Point Exception. • If an FPE occurs, the system can take a specified action: • abort • ignore the exception • repair the illegal condition • You can manipulate the status register to select action: • with calls to the FPE library, link with -lfpe • with environment variable TRAP_FPE • see man handle_sigfpes

  22. Compiler-Generated Exceptions Do i=1,N if(a(i) .lt. eps) then x = x + 1/eps else x = x + 1/a(i) endif enddo #put eps in $f1 and (1/eps) in $f0 ldc1 $f5,-8($2) load a(i) c.lt.d $fcc0,$f5,$f1 if(a(i) < eps) recip.d $f2,$f5 1/a(i) movt.d $f2,$f0,$fcc0 y = 1/a or 1/eps add.d $f1,$f1,$f2 x = x+ y • compiler can do more optimizations if it is allowed to generate code that could cause exceptions (-TENV:X=0..4) • X = 0 no speculative code motion • X = 1 IEEE-754 underflow and inexact FPE disabled (default -O0 and -O2) • X = 2 all IEEE-754 exceptions disabled except 1/0 (default -O3) • X = 3 all IEEE-754 exceptions are disabled • X = 4 memory access exceptions are disabled • IF-conversion with conditional moves for Software Pipelining (with -O3): Removing IF(…) will cause divide by zero! In this case this exception must be ignored Note: transf applied already at -O3 & X=1!

  23. IEEE_754 Compliance y_tmp = 1/y do i=1,n x = x + a(I)*y_tmp enddo Do i=1,n x = x + a(i)/y enddo • The MIPS4 instruction set contains IEEE-754 non-compliant instructions: • recip.s/d (reciprocal 1/x) instruction is accurate to 1 ulp • rsqrt.s/d (reciprocal-sqrt: 1/sqrt(x)) instruction to 2 ulp • -OPT:IEEE_arithmetic=X specify degree of non-compliance • and what to do with inf and NaN operands • X=1 strict IEEE-754 compliance; does not use the recip and rsqrt instructions (-O1,2) • X=2 optimize 0*x=0 and x/x=1 while x can be NaN (default at -O3) • X=3 any mathematically valid transformation is allowed, including recip & rsqrt instr. -O3 -OPT:IEEE_arithmetic=3 21 cycles/iteration; 4% peak 1 cycles/iteration; 100% peak Note: X=3 is required!

  24. Rounding Accuracy do i=1,n,8 x0 = x0 + a(i) x1 = x1 + a(i+1) … enddo x = x0 + x1 + … do i=1,n x = x + a(i) enddo -O3 -OPT:roundoff=2 (default at -O3) • Rounding mode can be specified with -OPT:roundoff=X switch: • X = 0 no optimizations that affect fp behaviour (default at -O1 -O2) • X = 1 allows simple transformations with limited round-off and overflow differences • X = 2 allows reordering of reduction loops (default at -O3) • X = 3 any mathematically valid transformation is allowed With -O3 -OPT:roundoff=1 2 cycles/iter; 25% peak 1 cycles/iter; 50% peak Recommendation: Your program should work correctly when compiled with -O3 -OPT:IEEE_arithmetic=3:roundoff=3

  25. Summary • Compiler is the primary tool of program optimization • compilation is the process of lowering the code representation from high level to low, I.e. processor level • the MipsPro compiler targets the MIPS R1x000 processor and has build in the features of the processor and Origin2000 architecture • A large number of options exist to steer the compilation process • ABI, ISA and optimization options selections • setting of assumptions about the program behaviour • there are optimized and parallelized libraries of subroutines for scientific computation • when programming for a digital computer, it is important to remember the limitations due to limited validity range of the floating point calculations

More Related