This URL is http://www.stewart.cs.sdsu.edu/cs575/lecs/ch7.html
Chapter 6 covered tools for runtime profiling of the behavior of the user source code. Chapter 7 points out user coding to avoid since it can defeat the possible optimizations a compiler would do for you.
f90 -Xlist f_diffusion.f sgeco.f sgesl.f blas.f
produces a
listing
How do we obtain a similar view of your code when using C?
cflow, cscope, dbx, gdb have been
suggested.
Your suggestions?
Do I=1,N A(I) = A(I) + B(I) * C ENDDOor the nested call
DO I=1,N CALL MADD (A(I), B(I), C) ENDDO SUBROUTINE MADD (A, B, C) A = A + B*C RETURN ENDThis is an example of a lot of subroutine overhead to accomplish a simple task.
Another example is the use of COMMON blocks in Fortran, typically used for global values.
COMMON /USELESS/ K DO K=1,1000 IF (K .EQ. 1) CALL AUX ENDDO
p. 131 text "Remember, if the function or subroutine does a reasonable amount of work, procedure call overhead isn't going to matter very much."
#define average (x,y) ( (x+y)/2 ) main() { float q=100, p=50; float a; a = average (p,q); printf ("%f\n",a); }The C preprocessor cpp expands all #define statement inline (as patterns).
a = average (p,q); is replaced by a = ((p+q)/2);A more problematic example:
#define multiply (a,b) (a*b) invoked as c = multiply (x+t,y+v) results in x+t*y+v not the intentionOh for a missing set of parenthesis.
PARAMETER (SMALL = 1.0E-20) DO I=1,N IF (ABS(A(I)) .GE. SMALL) THEN B(I) = B(I) + A(I) * C ENDIF ENDDOIn the olden days, the cost of a floating point multiply was so extensive that in a lengthy loop (large N), you would pay the cost of the comparison and absolute value to avoid it.
DO I=1,K IF (N .EQ. 0) THEN A(I) = A(I) + B(I) * C ELSE A(I) = 0. ENDIF ENDDOinvariant N will not change in the loop, therefore the result of the test on N (setting the value of A) won't change. Recast the loop by making the text outside the loop and replacing the loop body twice for each case:
IF (N .EQ. 0) THEN DO I=1,K A(I) = A(I) + B(I)*C ENDDO ELSE DO I=1,K A(I) = 0 ENDDO ENDIFMuch easier for the compiler to pipeline since the IF-statement is outside the loop.
DO I=1,N DO J=1,N IF (J .LT. I) A(J,I) = A(J,I) + B(J,I)*C ELSE A(J,I) = 0.0 ENDIF ENDDO ENDDO
These nested loops easily predict when J < I, so having a logical test is unneeded. Better to write code as:
DO I=1,N DO J=1,I-1 A(J,I) = A(J,I) + B(J,I)*C ENDDO DO J=I,N A(J,I) = 0.0 ENDDO ENDDO