Reducers address the problem of accessing nonlocal variables in parallel code. Conceptually, a reducer is a variable that can be safely used by multiple strands running in parallel. The runtime ensures that each worker has access to a private copy of the variable, eliminating the possibility of races without requiring locks. When the strands synchronize, the reducer copies are merged (or reduced) into a single variable. The runtime creates copies only when needed, minimizing overhead.
Reducers have several attractive properties:
Reducers allow reliable access to nonlocal variables without races.
Reducers do not require locks and therefore avoid the problem of lock contention (and subsequent loss of parallelism) that arises from using locks to protect nonlocal variables.
Defined and used correctly, reducers retain serial semantics. The result of a program that uses reducers is the same as the serial version, and the result does not depend on the number of processors or how the workers are scheduled. Reducers can be used without significantly restructuring existing code.
Reducers are implemented efficiently, incurring minimal overhead.
Reducers can be used independently of the program's control structure, unlike constructs that are defined over specific control structures such as loops.
Reducers are defined by writing C++ templates that provide an interface to the runtime system.
At some point, you may want to write your own reducer. How to Write a New Reducer provides more information.
Copyright © 1996-2011, Intel Corporation. All rights reserved.