OpenMP: Difference between revisions

From GRASS-Wiki
Jump to navigation Jump to search
(→‎Candidates: use a profiling tool)
Line 94: Line 94:


* Yann has added OpenMP support to {{cmd|i.atcorr}}. (not in SVN)
* Yann has added OpenMP support to {{cmd|i.atcorr}}. (not in SVN)
== Alternatives ==
* {{wikipedia|pthreads}}
* Poor-man's multithreading using Bourne shell script & backgrounding:
For example:
### r.sun mode 1 loop ###
SUNRISE=7.67
SUNSET=16.33
STEP=0.01
# | wc -l  867
CORES=4
DAY=355
for TIME in `seq $SUNRISE $STEP $SUNSET` ; do
    echo "time=$TIME"
    CMD="r.sun -s elevin=gauss day=$DAY time=$TIME \
          beam_rad=rad1_test.${DAY}_${TIME}_beam --quiet"
    # poor man's multi-threading for a multi-core CPU
    MODULUS=`echo "$TIME $STEP $CORES" | awk '{print $1 % ($2 * $3)}'`
    if [ "$MODULUS" = "$STEP" ] ; then
      # stall to let the background jobs finish
      $CMD
      sleep 2
      #while [ `pgrep -c r.sun` -ne 0 ] ; do
      #  sleep 5
      #done
    else
      $CMD &
    fi
done


== See also ==
== See also ==

Revision as of 04:46, 13 August 2009

Multithreaded jobs in GRASS

OpenMP is an implementation of multithreading, a method of parallelization whereby the master "thread" (a series of instructions executed consecutively) "forks" a specified number of slave "threads" and a task is divided among them (from wikipedia). The job is distributed over the available processor cores (2-core, 4-core, ...).

The (yet) only parallelized library in GRASS >=6.3 is GRASS Partial Differential Equations Library (GPDE). The library design is thread safe and supports threaded parallelism with OpenMP. The code is not yet widely used in GRASS. See here for details.

How to activate it with GCC >= 4.2 (compiler flag '-fopenmp' as well as library '-lgomp' are needed):

# GPDE with openMP support:

cd lib/gpde/
vim Makefile
# uncomment the EXTRA_CFLAGS row and switch the two existing EXTRA_LIBS rows


Integrated system-wide support for OpenMP via a --with-openmp ./configure flag has been requested in trac #657.

General code structure

Example cited from "openMP tutorial" (see below):

   #include <omp.h>
  
   int main ()  {
       int var1, var2, var3;
   
       Some serial code 
       ...
  
       /* Beginning of parallel section. Fork a team of threads. */
       /* Specify variable scoping */
  
      #pragma omp parallel private(var1, var2) shared(var3)
      {
  
       /* Parallel section executed by all threads */
       ...
  
       /* All threads join master thread and disband */
      }  /* end pragma */
  
      /* Resume serial code */
      ...
  
   }

And in the Makefile, add something like this:

  #openMP support
  EXTRA_CFLAGS=-fopenmp
  EXTRA_LIBS=$(GISLIB) -lgomp $(MATHLIB)
  • Examples:
https://computing.llnl.gov/tutorials/openMP/exercise.html

Run time

The default is to create as many threads as the system has processors. If you don't want that, you can control the number with the OMP_NUM_THREADS environment variable. For example to request 3 threads from a Bourne shell:

OMP_NUM_THREADS=3
export OMP_NUM_THREADS

g.module ...

Candidates

It is important to understand which modules are processor bound, and concentrate on them. i.e. do not needlessly complicate the code of non-long running processor bound or I/O-bound modules. Almost all of the GIS libraries are not thread-safe. Regardless, these are typically I/O bound not processor bound, so not critical to parallelize. It is expected that most of the CPU-bound loops which will benefit from parallelization will be found in the modules.

A good place to start is by running a profiling tool to find the worst offending functions and deal with them first. Blindly parallelizing every loop you can find has the potential to slow things down due to the overheads needed to create and destroy threads.

This would speed up the CPU-bound v.surf.bspline and v.lidar.edgedetection considerably.
Please contact and coordinate with Helena Mitasova before starting work on this.
Please contact and coordinate with Markus Metz before starting work on this.
Please contact and coordinate with Laura Toma before starting work on this.
Should fix bug described in trac #390 first and once that is done move module into the main repo.
Please contact and coordinate with Markus Neteler / Jaro Hofierka before starting work on this.

Complete

  • The GPDE library (lib/gpde/) has OpenMP support (disabled by default)
  • GRASS 7 has a ./configure switch for `--with-pthread`
  • Yann has added OpenMP support to i.atcorr. (not in SVN)

Alternatives

  • pthreads
  • Poor-man's multithreading using Bourne shell script & backgrounding:

For example:

### r.sun mode 1 loop ###
SUNRISE=7.67
SUNSET=16.33
STEP=0.01
# | wc -l   867
CORES=4

DAY=355
for TIME in `seq $SUNRISE $STEP $SUNSET` ; do
   echo "time=$TIME"
   CMD="r.sun -s elevin=gauss day=$DAY time=$TIME \
         beam_rad=rad1_test.${DAY}_${TIME}_beam --quiet"

   # poor man's multi-threading for a multi-core CPU
   MODULUS=`echo "$TIME $STEP $CORES" | awk '{print $1 % ($2 * $3)}'`
   if [ "$MODULUS" = "$STEP" ] ; then
      # stall to let the background jobs finish
      $CMD
      sleep 2
      #while [ `pgrep -c r.sun` -ne 0 ] ; do
      #   sleep 5
      #done
   else
     $CMD &
   fi
done

See also