gcc


Introduction:

GCC officially stands for the "GNU Compiler Collection";
Although GCC is most commonly thought of as the Gnu C Compiler (gcc),
the collection includes compilers for C++ (g++),
FORTRAN (gfortran) and even the Google language GO
(gccgo).

Most of the features of the GNU C compiler are also common to
g++ and gfortran.

In its most common use, the GCC compiler takes user source code written
in the C language, checks it for correctness, converts it into
relocatable code, adds in system and user libraries that are properly
referenced, and creates a program that can be executed.

For a simple program hello.c, these steps could be broken down
as follows:

      gcc -c hello.c     <-- check hello.c, create relocatable hello.o
      gcc hello.o        <-- add libraries to hello.o, create a.out
      mv a.out hello     <-- rename executable to "hello"
    

or these steps can be combined into:

      gcc hello.c -o hello
    

after which the program can be run by:

      ./hello            <-- run program by name.
    

Two common complications to the procedure are include files
and precompiled libraries. On a cluster computer, the user
may write a main program, say myprog.c, which needs to access
functions in a precompiled library maintained by the system
administrators. The user may be told that the directory of
include files has the symbolic name $BLAS_INC and the library
directory has the symbolic name $BLAS_LIB, while the library file
itself might be called libblas.a. In that case, the
compilation procedure might look like this:

      gcc -c -I$BLAS_INC myprog.c     <-- use includes from this directory
      gcc myprog.o -L$BLAS_LIB -lblas <-- use libblas.a from this directory
      mv a.out myprog                 <-- rename executable as usual
    

although the first three steps can be combined into

      gcc  -I$BLAS_INC hello.c -o hello -L$BLAS_LIB -lblas
    

GCC has an enormous number of switches that modify its behavior.
Two convenient ones are -Wall:

      gcc -Wall myprog.c
    

which tells the compiler to report even minor coding discrepancies.

Another compiler switch is -Olevel, where 0 indicates
no optimization, and 3 indicates an aggressive optimization effort:

      gcc -O3 myprog.c
    

This can sometimes produce a significant speedup in execution time.
Sometimes, however, a compiler optimization can be erroneous, so
it's important to compare the results of the optimized code to the
original version to make sure nothing has gone seriously wrong.

Another feature of GCC allows the user to define macro variables,
optionally including a value, which can be specified at compilation,
and affect the behavior of he program. A common
practice is to allow the definition of the variable DEBUG, as in:

      gcc -DDEBUG myprog.c
    

Within the program, there would then be lines such as

      # ifdef DEBUG
        print_arrays ( a, b, c );
      # else
        printf ( "Printout of arrays is omitted.\n" );
      # endif
    

GCC can also process OpenMP compiler directives. This requires the
command line switch -fopenmp, as in

      gcc -fopenmp myprog.c
    

The resulting program can take advantage of multiple cores on a
shared memory process. The degree to which the program parallelizes
is typically controlled by setting an environment variable before the
program is executed:

      gcc -fopenmp -o myprog myprog.c
      export OMP_NUM_THREADS=8
      ./myprog
    

Versions of the GCC compilers are available for use with MPI,
with the names mpicc, mpic++, mpif77, and
mpif90.

Web site:


https://gcc.gnu.org/

Reference:

Usage:

On any ARC cluster, check the installation details
by typing "module spider gcc".

GCC requires that the appropriate module be loaded before it can be run.
One version of the appropriate commands for use on NewRiver is:

module purge
module load gcc/5.2.0
    

Examples:

The following batch file demonstrates a few ways to use the GCC C compiler.
A program is compiled in three steps, then in one step with a commandline
macro "PRINT", and the compiled and run four times with increasing levels
of optimization.

#! /bin/bash
#
#PBS -l walltime=5:00
#PBS -l nodes=1:ppn=1
#PBS -q open_q
#PBS -W group_list=newriver
#PBS -j oe

cd $PBS_O_WORKDIR
#
module purge
module load gcc/5.2.0
#
#  3 step compile, load, rename:
#
gcc -c heated_plate.c
gcc heated_plate.o
mv a.out heated_plate
./heated_plate
rm heated_plate.o
rm heated_plate
#
#  1 step compile, load, rename.
#  Also set commandline "PRINT" macro, so program will print data.
#
gcc -DPRINT -o heated_plate heated_plate.c
./heated_plate
rm heated_plate
#
#  Compile with optimization levels 0, 1, 2, 3 and time the results.
#
if [ -f gcc_timings.txt ]; then
  rm gcc_timings.txt
fi

for n in 0 1 2 3;
do
  echo "Compile with gcc optimization level -O$n"
  gcc -O$n -o heated_plate heated_plate.c
  time ( ./heated_plate ) 2>> gcc_timings.txt
done
rm heated_plate

A complete set of files to carry out a similar process are available in
gcc_example.tar