annotate src/fftw-3.3.8/doc/threads.texi @ 82:d0c2a83c1364

Add FFTW 3.3.8 source, and a Linux build
author Chris Cannam
date Tue, 19 Nov 2019 14:52:55 +0000
parents
children
rev   line source
Chris@82 1 @node Multi-threaded FFTW, Distributed-memory FFTW with MPI, FFTW Reference, Top
Chris@82 2 @chapter Multi-threaded FFTW
Chris@82 3
Chris@82 4 @cindex parallel transform
Chris@82 5 In this chapter we document the parallel FFTW routines for
Chris@82 6 shared-memory parallel hardware. These routines, which support
Chris@82 7 parallel one- and multi-dimensional transforms of both real and
Chris@82 8 complex data, are the easiest way to take advantage of multiple
Chris@82 9 processors with FFTW. They work just like the corresponding
Chris@82 10 uniprocessor transform routines, except that you have an extra
Chris@82 11 initialization routine to call, and there is a routine to set the
Chris@82 12 number of threads to employ. Any program that uses the uniprocessor
Chris@82 13 FFTW can therefore be trivially modified to use the multi-threaded
Chris@82 14 FFTW.
Chris@82 15
Chris@82 16 A shared-memory machine is one in which all CPUs can directly access
Chris@82 17 the same main memory, and such machines are now common due to the
Chris@82 18 ubiquity of multi-core CPUs. FFTW's multi-threading support allows
Chris@82 19 you to utilize these additional CPUs transparently from a single
Chris@82 20 program. However, this does not necessarily translate into
Chris@82 21 performance gains---when multiple threads/CPUs are employed, there is
Chris@82 22 an overhead required for synchronization that may outweigh the
Chris@82 23 computatational parallelism. Therefore, you can only benefit from
Chris@82 24 threads if your problem is sufficiently large.
Chris@82 25 @cindex shared-memory
Chris@82 26 @cindex threads
Chris@82 27
Chris@82 28 @menu
Chris@82 29 * Installation and Supported Hardware/Software::
Chris@82 30 * Usage of Multi-threaded FFTW::
Chris@82 31 * How Many Threads to Use?::
Chris@82 32 * Thread safety::
Chris@82 33 @end menu
Chris@82 34
Chris@82 35 @c ------------------------------------------------------------
Chris@82 36 @node Installation and Supported Hardware/Software, Usage of Multi-threaded FFTW, Multi-threaded FFTW, Multi-threaded FFTW
Chris@82 37 @section Installation and Supported Hardware/Software
Chris@82 38
Chris@82 39 All of the FFTW threads code is located in the @code{threads}
Chris@82 40 subdirectory of the FFTW package. On Unix systems, the FFTW threads
Chris@82 41 libraries and header files can be automatically configured, compiled,
Chris@82 42 and installed along with the uniprocessor FFTW libraries simply by
Chris@82 43 including @code{--enable-threads} in the flags to the @code{configure}
Chris@82 44 script (@pxref{Installation on Unix}), or @code{--enable-openmp} to use
Chris@82 45 @uref{http://www.openmp.org,OpenMP} threads.
Chris@82 46 @fpindex configure
Chris@82 47
Chris@82 48
Chris@82 49 @cindex portability
Chris@82 50 @cindex OpenMP
Chris@82 51 The threads routines require your operating system to have some sort
Chris@82 52 of shared-memory threads support. Specifically, the FFTW threads
Chris@82 53 package works with POSIX threads (available on most Unix variants,
Chris@82 54 from GNU/Linux to MacOS X) and Win32 threads. OpenMP threads, which
Chris@82 55 are supported in many common compilers (e.g. gcc) are also supported,
Chris@82 56 and may give better performance on some systems. (OpenMP threads are
Chris@82 57 also useful if you are employing OpenMP in your own code, in order to
Chris@82 58 minimize conflicts between threading models.) If you have a
Chris@82 59 shared-memory machine that uses a different threads API, it should be
Chris@82 60 a simple matter of programming to include support for it; see the file
Chris@82 61 @code{threads/threads.c} for more detail.
Chris@82 62
Chris@82 63 You can compile FFTW with @emph{both} @code{--enable-threads} and
Chris@82 64 @code{--enable-openmp} at the same time, since they install libraries
Chris@82 65 with different names (@samp{fftw3_threads} and @samp{fftw3_omp}, as
Chris@82 66 described below). However, your programs may only link to @emph{one}
Chris@82 67 of these two libraries at a time.
Chris@82 68
Chris@82 69 Ideally, of course, you should also have multiple processors in order to
Chris@82 70 get any benefit from the threaded transforms.
Chris@82 71
Chris@82 72 @c ------------------------------------------------------------
Chris@82 73 @node Usage of Multi-threaded FFTW, How Many Threads to Use?, Installation and Supported Hardware/Software, Multi-threaded FFTW
Chris@82 74 @section Usage of Multi-threaded FFTW
Chris@82 75
Chris@82 76 Here, it is assumed that the reader is already familiar with the usage
Chris@82 77 of the uniprocessor FFTW routines, described elsewhere in this manual.
Chris@82 78 We only describe what one has to change in order to use the
Chris@82 79 multi-threaded routines.
Chris@82 80
Chris@82 81 @cindex OpenMP
Chris@82 82 First, programs using the parallel complex transforms should be linked
Chris@82 83 with @code{-lfftw3_threads -lfftw3 -lm} on Unix, or @code{-lfftw3_omp
Chris@82 84 -lfftw3 -lm} if you compiled with OpenMP. You will also need to link
Chris@82 85 with whatever library is responsible for threads on your system
Chris@82 86 (e.g. @code{-lpthread} on GNU/Linux) or include whatever compiler flag
Chris@82 87 enables OpenMP (e.g. @code{-fopenmp} with gcc).
Chris@82 88 @cindex linking on Unix
Chris@82 89
Chris@82 90
Chris@82 91 Second, before calling @emph{any} FFTW routines, you should call the
Chris@82 92 function:
Chris@82 93
Chris@82 94 @example
Chris@82 95 int fftw_init_threads(void);
Chris@82 96 @end example
Chris@82 97 @findex fftw_init_threads
Chris@82 98
Chris@82 99 This function, which need only be called once, performs any one-time
Chris@82 100 initialization required to use threads on your system. It returns zero
Chris@82 101 if there was some error (which should not happen under normal
Chris@82 102 circumstances) and a non-zero value otherwise.
Chris@82 103
Chris@82 104 Third, before creating a plan that you want to parallelize, you should
Chris@82 105 call:
Chris@82 106
Chris@82 107 @example
Chris@82 108 void fftw_plan_with_nthreads(int nthreads);
Chris@82 109 @end example
Chris@82 110 @findex fftw_plan_with_nthreads
Chris@82 111
Chris@82 112 The @code{nthreads} argument indicates the number of threads you want
Chris@82 113 FFTW to use (or actually, the maximum number). All plans subsequently
Chris@82 114 created with any planner routine will use that many threads. You can
Chris@82 115 call @code{fftw_plan_with_nthreads}, create some plans, call
Chris@82 116 @code{fftw_plan_with_nthreads} again with a different argument, and
Chris@82 117 create some more plans for a new number of threads. Plans already created
Chris@82 118 before a call to @code{fftw_plan_with_nthreads} are unaffected. If you
Chris@82 119 pass an @code{nthreads} argument of @code{1} (the default), threads are
Chris@82 120 disabled for subsequent plans.
Chris@82 121
Chris@82 122 @cindex OpenMP
Chris@82 123 With OpenMP, to configure FFTW to use all of the currently running
Chris@82 124 OpenMP threads (set by @code{omp_set_num_threads(nthreads)} or by the
Chris@82 125 @code{OMP_NUM_THREADS} environment variable), you can do:
Chris@82 126 @code{fftw_plan_with_nthreads(omp_get_max_threads())}. (The @samp{omp_}
Chris@82 127 OpenMP functions are declared via @code{#include <omp.h>}.)
Chris@82 128
Chris@82 129 @cindex thread safety
Chris@82 130 Given a plan, you then execute it as usual with
Chris@82 131 @code{fftw_execute(plan)}, and the execution will use the number of
Chris@82 132 threads specified when the plan was created. When done, you destroy
Chris@82 133 it as usual with @code{fftw_destroy_plan}. As described in
Chris@82 134 @ref{Thread safety}, plan @emph{execution} is thread-safe, but plan
Chris@82 135 creation and destruction are @emph{not}: you should create/destroy
Chris@82 136 plans only from a single thread, but can safely execute multiple plans
Chris@82 137 in parallel.
Chris@82 138
Chris@82 139 There is one additional routine: if you want to get rid of all memory
Chris@82 140 and other resources allocated internally by FFTW, you can call:
Chris@82 141
Chris@82 142 @example
Chris@82 143 void fftw_cleanup_threads(void);
Chris@82 144 @end example
Chris@82 145 @findex fftw_cleanup_threads
Chris@82 146
Chris@82 147 which is much like the @code{fftw_cleanup()} function except that it
Chris@82 148 also gets rid of threads-related data. You must @emph{not} execute any
Chris@82 149 previously created plans after calling this function.
Chris@82 150
Chris@82 151 We should also mention one other restriction: if you save wisdom from a
Chris@82 152 program using the multi-threaded FFTW, that wisdom @emph{cannot be used}
Chris@82 153 by a program using only the single-threaded FFTW (i.e. not calling
Chris@82 154 @code{fftw_init_threads}). @xref{Words of Wisdom-Saving Plans}.
Chris@82 155
Chris@82 156 @c ------------------------------------------------------------
Chris@82 157 @node How Many Threads to Use?, Thread safety, Usage of Multi-threaded FFTW, Multi-threaded FFTW
Chris@82 158 @section How Many Threads to Use?
Chris@82 159
Chris@82 160 @cindex number of threads
Chris@82 161 There is a fair amount of overhead involved in synchronizing threads,
Chris@82 162 so the optimal number of threads to use depends upon the size of the
Chris@82 163 transform as well as on the number of processors you have.
Chris@82 164
Chris@82 165 As a general rule, you don't want to use more threads than you have
Chris@82 166 processors. (Using more threads will work, but there will be extra
Chris@82 167 overhead with no benefit.) In fact, if the problem size is too small,
Chris@82 168 you may want to use fewer threads than you have processors.
Chris@82 169
Chris@82 170 You will have to experiment with your system to see what level of
Chris@82 171 parallelization is best for your problem size. Typically, the problem
Chris@82 172 will have to involve at least a few thousand data points before threads
Chris@82 173 become beneficial. If you plan with @code{FFTW_PATIENT}, it will
Chris@82 174 automatically disable threads for sizes that don't benefit from
Chris@82 175 parallelization.
Chris@82 176 @ctindex FFTW_PATIENT
Chris@82 177
Chris@82 178 @c ------------------------------------------------------------
Chris@82 179 @node Thread safety, , How Many Threads to Use?, Multi-threaded FFTW
Chris@82 180 @section Thread safety
Chris@82 181
Chris@82 182 @cindex threads
Chris@82 183 @cindex OpenMP
Chris@82 184 @cindex thread safety
Chris@82 185 Users writing multi-threaded programs (including OpenMP) must concern
Chris@82 186 themselves with the @dfn{thread safety} of the libraries they
Chris@82 187 use---that is, whether it is safe to call routines in parallel from
Chris@82 188 multiple threads. FFTW can be used in such an environment, but some
Chris@82 189 care must be taken because the planner routines share data
Chris@82 190 (e.g. wisdom and trigonometric tables) between calls and plans.
Chris@82 191
Chris@82 192 The upshot is that the only thread-safe routine in FFTW is
Chris@82 193 @code{fftw_execute} (and the new-array variants thereof). All other routines
Chris@82 194 (e.g. the planner) should only be called from one thread at a time. So,
Chris@82 195 for example, you can wrap a semaphore lock around any calls to the
Chris@82 196 planner; even more simply, you can just create all of your plans from
Chris@82 197 one thread. We do not think this should be an important restriction
Chris@82 198 (FFTW is designed for the situation where the only performance-sensitive
Chris@82 199 code is the actual execution of the transform), and the benefits of
Chris@82 200 shared data between plans are great.
Chris@82 201
Chris@82 202 Note also that, since the plan is not modified by @code{fftw_execute},
Chris@82 203 it is safe to execute the @emph{same plan} in parallel by multiple
Chris@82 204 threads. However, since a given plan operates by default on a fixed
Chris@82 205 array, you need to use one of the new-array execute functions (@pxref{New-array Execute Functions}) so that different threads compute the transform of different data.
Chris@82 206
Chris@82 207 (Users should note that these comments only apply to programs using
Chris@82 208 shared-memory threads or OpenMP. Parallelism using MPI or forked processes
Chris@82 209 involves a separate address-space and global variables for each process,
Chris@82 210 and is not susceptible to problems of this sort.)
Chris@82 211
Chris@82 212 The FFTW planner is intended to be called from a single thread. If you
Chris@82 213 really must call it from multiple threads, you are expected to grab
Chris@82 214 whatever lock makes sense for your application, with the understanding
Chris@82 215 that you may be holding that lock for a long time, which is undesirable.
Chris@82 216
Chris@82 217 Neither strategy works, however, in the following situation. The
Chris@82 218 ``application'' is structured as a set of ``plugins'' which are unaware
Chris@82 219 of each other, and for whatever reason the ``plugins'' cannot coordinate
Chris@82 220 on grabbing the lock. (This is not a technical problem, but an
Chris@82 221 organizational one. The ``plugins'' are written by independent agents,
Chris@82 222 and from the perspective of each plugin's author, each plugin is using
Chris@82 223 FFTW correctly from a single thread.) To cope with this situation,
Chris@82 224 starting from FFTW-3.3.5, FFTW supports an API to make the planner
Chris@82 225 thread-safe:
Chris@82 226
Chris@82 227 @example
Chris@82 228 void fftw_make_planner_thread_safe(void);
Chris@82 229 @end example
Chris@82 230 @findex fftw_make_planner_thread_safe
Chris@82 231
Chris@82 232 This call operates by brute force: It just installs a hook that wraps a
Chris@82 233 lock (chosen by us) around all planner calls. So there is no magic and
Chris@82 234 you get the worst of all worlds. The planner is still single-threaded,
Chris@82 235 but you cannot choose which lock to use. The planner still holds the
Chris@82 236 lock for a long time, but you cannot impose a timeout on lock
Chris@82 237 acquisition. As of FFTW-3.3.5 and FFTW-3.3.6, this call does not work
Chris@82 238 when using OpenMP as threading substrate. (Suggestions on what to do
Chris@82 239 about this bug are welcome.) @emph{Do not use
Chris@82 240 @code{fftw_make_planner_thread_safe} unless there is no other choice,}
Chris@82 241 such as in the application/plugin situation.