IDL allows you to programmatically control of thread pool use. This section discusses the following aspects of thread pool use:
Note: Multithreading does not offer the possibility of increased execution speed for all IDL routines. For a list of the routines that have been implemented to use multithreading when possible, see Routines that Use the Thread Pool.
Viewing the Current Thread Pool Settings
The current values of the parameters that control IDL’s use of the thread pool for computations are always available in the read-only !CPU system variable. !CPU is initialized by IDL at startup with default values for the number of CPUs (threads) to use, as well as the minimum and maximum number of data elements. To view the settings, use the following command:
HELP, /STRUCTURE, !CPU
The values of the fields in the !CPU system variable are explained in !CPU.
Using the Default Thread Pool Settings
If you have more than one processor on your system, if the routine you are using is able to use the thread pool, and if the number of data elements in your computation falls into the allowed range (neither too few nor too many), then IDL will employ the thread pool in that calculation.
If the above requirements are met, IDL will automatically use the thread pool for the computation. You do not need to do anything special to enable IDL’s multithreading capabilities.
Changing Global Thread Pool Settings
Unless they are overridden by thread pool keywords supplied at the time of execution, the values contained in the !CPU system variable control IDL’s use of the thread pool. !CPU is a “read-only” system variable, which means that you cannot assign values to its structure fields directly, either at the command line or within a program. However, you can set the default number of threads prior to starting IDL by using the IDL_CPU_TPOOL_NTHREADS preference. See !CPU Settings Preferences for details. You can also change the values of the !CPU system variable for the duration of the current IDL session by using the CPU procedure.
The CPU procedure accepts the following keywords:
TPOOL_MAX_ELTS
Set this keyword to a non-zero value to set the maximum number of data elements involved in a computation that uses the thread pool. If the number of elements in the computation exceeds the number you specify, IDL will not use the thread pool for the computation. Setting this value to 0 removes any limit on maximum number of elements, and any computation with at least TPOOL_MIN_ELTS will use the thread pool.
This keyword changes the value returned by !CPU.TPOOL_MAX_ELTS.
TPOOL_MIN_ELTS
Set this keyword to a non-zero value to set the minimum number of data elements involved in a computation that uses the thread pool. If the number of elements in the computation is less than the number you specify, IDL will not use the thread pool for the computation. Use this keyword to prevent IDL from using the thread pool on tasks that are too small to benefit from it.
This keyword changes the value returned by !CPU.TPOOL_MIN_ELTS.
TPOOL_NTHREADS
Set this keyword to the number of threads IDL should use when performing computations that take advantage of the thread pool. By default, IDL will use !CPU.HW_NCPU threads, so that each thread will have the potential to run in parallel with the others. Set this keyword equal to 0 (zero) to ensure that !CPU.HW_NCPU threads will be used. Set this keyword equal to 1 (one) to disable use of the thread pool.
This keyword changes the value returned by !CPU.TPOOL.NTHREADS.
Note: For numerical computation, there is no benefit to using more threads than your system has CPUs. However, depending on the size of the problem and the number of other programs running on the system, there may be a performance advantage to using fewer CPUs. See Possible Drawbacks to Using the Thread Pool for a discussion of the circumstances under which using fewer than the maximum number of CPUs makes sense.
For more information on the CPU procedure, see CPU.
Examples
The following examples illustrate use of the CPU procedure to modify IDL’s global thread pool settings.
Note: The following examples are designed for systems with more than one processor. The examples will generate correct results on single-processor systems, but may run more slowly than the same operations performed without the thread pool.
Example 1
As a first example, imagine that we want to ensure that the thread pool is not used unless there are at least 50,000 data elements. We set the minimum to 50,000 since we know, for our system, that at least 50,000 floating point data elements are required before the thread pool use will exceed the overhead required to use it.
In addition, we want to ensure that the thread pool is not used if a calculation involves more than 1,000,000 data elements. We set the maximum to 1,000,000 since we know that 1,000,000 floating point data elements will exceed the maximum amount of memory available for the computation, requiring the use of virtual memory.
The following IDL statements use the CPU procedure to modify the minimum and maximum number of elements used in thread pool computations, create an array of floating-point values, and perform a computation on the array:
CPU, TPOOL_MAX_ELTS = 1000000, TPOOL_MIN_ELTS = 50000
theta = FINDGEN(361, 181)
sineSquared = 1. - (COS(!DTOR*theta))^2
In this example, the thread pool will be used since we are performing a computation on an array of 361 x 181 = 65,341 data elements, which falls between the minimum and maximum thresholds. Note that we altered the global thread pool parameters in such a way that the computation was allowed. The values set by the CPU procedure will remain in effect, either until they are changed again by another call to CPU or until the end of the IDL session. An alternative approach that does not change the global defaults in shown in Changing Thread Pool Settings for a Specific Computation.
Example 2
In this example, we will:
- Save the current thread pool settings from the !CPU system variable.
- Modify the thread pool settings so that IDL is configured, for our particular system, to efficiently perform a floating point computation.
- Perform several floating point computations.
- Modify the thread pool settings so that IDL is configured, for our particular system, to efficiently perform a double precision computation.
- Perform several double precision computations.
- Restore the thread pool settings to their original values.
The first computation will use the thread pool since it does not exceed any of the specified parameters. The second computation, since it exceeds the maximum number of data elements, will not use the thread pool.
threadpool = !CPU
CPU, TPOOL_MAX_ELTS = 1000000, TPOOL_MIN_ELTS = 50000, $
TPOOL_NTHREADS = 2
theta = FINDGEN(361, 181)
sineSquared = 1. - (COS(!DTOR*theta))^2
next computation
next computation
etc.
CPU, TPOOL_MAX_ELTS = 50000, TPOOL_MIN_ELTS = 10000
theta = DINDGEN(361, 181)
sineSquared = 1. - (COS(!DTOR*theta))^2
next computation
next computation
etc.
CPU, TPOOL_MAX_ELTS = threadpool.TPOOL_MAX_ELTS, $
TPOOL_MIN_ELTS = threadpool.TPOOL_MIN_ELTS, $
TPOOL_NTHREADS = threadpool.HW_NCPU
Again, in this example we altered the global thread pool parameters. In cases where you plan to perform multiple computations that take advantage of the same thread pool configuration, changing the global thread pool parameters is convenient. In cases where only a single computation uses the specified thread pool configuration, it is easier to use the thread pool keywords to the routine that performs the computation, as described in the following section.
Changing Thread Pool Settings for a Specific Computation
All routines that have been implemented to use the thread pool accept keywords that allow you to override the thread pool settings stored in !CPU for a single invocation of the routine. This allows you to modify the settings for a particular computation without affecting the global default settings of your session. See Routines that Use the Thread Pool for more information.
The thread pool keywords are:
TPOOL_MAX_ELTS
Set this keyword to a non-zero value to set the maximum number of data elements involved in a computation that uses the thread pool. If the number of elements in the computation exceeds the number you specify, IDL will not use the thread pool for the computation. Setting this value to 0 removes any limit on the maximum number of elements, and any computation with at least TPOOL_MIN_ELTS will use the thread pool.
This keyword overrides the default value, given by !CPU.TPOOL_MAX_ELTS.
TPOOL_MIN_ELTS
Set this keyword to a non-zero value to set the minimum number of data elements involved in a computation that uses the thread pool. If the number of elements in the computation is less than the number you specify, IDL will not use the thread pool for the computation. Use this keyword to prevent IDL from using the thread pool on tasks that are too small to benefit from it.
This keyword overrides the default value, given by !CPU.TPOOL_MIN_ELTS.
TPOOL_NOTHREAD
Set this keyword to explicitly prevent IDL from using the thread pool for the current computation. If this keyword is set, IDL will use the non-threaded implementation of the routine even if the current settings of the !CPU system variable would allow use of the threaded implementation.
Example
We can use the TPOOL_MIN_ELTS and TPOOL_MAX_ELTS keywords to the COS function to modify the example used in the previous section so that our changes to the thread pool settings do not alter the global default.
theta = FINDGEN(361, 181)
sineSquared = 1. - (COS(!DTOR*theta, TPOOL_MAX_ELTS = 1000000, $
TPOOL_MIN_ELTS = 50000))^2
Disabling the Thread Pool
There are two ways to disable the thread pool in IDL:
- Use the CPU procedure to alter the global thread pool parameters.
- Use the TPOOL_NOTHREAD keyword to a routine to disable the thread pool for a specific single computation.
In the first example, we will disable the thread pool for the session by setting the number of threads to use to one:
CPU, TPOOL_NTHREADS = 1
In the next example, we will disable the thread pool for a specific computation using the TPOOL_NOTHREAD keyword:
sineSquared = 1. - (COS(!DTOR*theta, /TPOOL_NOTHREAD))^2
See Also
The IDL Thread Pool, Routines that Use the Thread Pool, Thread Pool Keywords