I. Introduction
In the parallel area, if multiple threads access the same storage unit together and at least one thread updates the content in the data unit, the data will be sent in this life. Data sharing and privatization in this section will make a preliminary discussion on data competition.Article.
2. Sharing and private variables in the parallel Zone
All variables in the parallel zone are shared except in the following three cases:
1. variables defined in the parallel Zone
2. Loop variables used by multiple threads to complete Loops
3. Variables modified by private, firstprivate, lastprivate, or function
For example:
# Include <iostream> <br/> # include <OMP. h> // header file to be included in OpenMP programming </P> <p> int main () <br/>{</P> <p> int defaults _a = 0; // shared variable <br/> int pai_to_private_ B = 1; // modify the variable using the private clause and then change it to a private variable in the parallel area </P> <p> # pragma OMP parallel <br/> {<br/> int private_c = 2; </P> <p> # pragma OMP for private (pai_to_private_ B) <br/> for (INT I = 0; I <10; ++ I) // The loop variable is private. If there are two threads, one thread executes 0 <= I <5, another thread executes 5 <= I <10 <br/>{< br/> STD: cout <I <STD: Endl; <br/>}</P> <p> return 0; <br/>}
Iii. Methods for sharing and private variable Declaration
Declare method Function
In the private (val1, val2,...) Parallel region, the variable Val is private, that is, each thread has a copy of the variable.
The difference between first_private (val1, val2,...) and private is that each thread initializes the variable at the beginning.
The difference between last_private (val1, val2,...) and private is that the private variable of the last loop of concurrent execution will be copied to Val
Shared (val1, val2,...) declares that Val is shared.
Iv. Private example
If private is used, the variable is not initialized no matter whether it is initialized outside the parallel zone.
In vs2008, private variables are not initialized and an error occurs. For example:
# Include <iostream> <br/> # include <OMP. h> // header file to be included in OpenMP programming </P> <p> int main () <br/>{< br/> int shared_to_private = 1; // After modifying the variable through the private clause, it becomes a private variable in the parallel zone. after entering the parallel zone, each thread will copy the variable, and will not be initialized </P> <p> # pragma OMP parallel for private (shared_to_private) <br/> for (INT I = 0; I <10; ++ I) <br/>{< br/> STD: cout <shared_to_private <STD: Endl; <br/>}</P> <p> return 0; <br/>}
After F5 is run, the output variable shared_to_private is collapsed because it is not initialized.
V. first_private example
# Include <iostream> <br/> # include <OMP. h> // header file to be included in OpenMP programming </P> <p> int main () <br/>{< br/> int shared_to_first_private = 1; // After modifying the variable through the firstprivate clause, it becomes a private variable in the parallel zone. after entering the parallel zone, each thread will copy the variable, </P> <p> # pragma OMP parallel for firstprivate (shared_to_first_private) <br/> for (INT I = 0; I <10; ++ I) <br/>{< br/> STD: cout <++ shared_to_first_private <STD: Endl; <br/>}</P> <p> return 0; <br/>}< br/>
Print as follows:
It can be seen that the private variable shared_to_first_private corresponding to the two threads is initialized to 1, and each cycle increases by 1.
Vi. last_private example
# Include <iostream> <br/> # include <OMP. h> // header file to be included in OpenMP programming </P> <p> int main () <br/>{< br/> int shared_to_last_private = 1; // After modifying the variable through the firstprivate clause, it becomes a private variable in the parallel zone. after entering the parallel zone, each thread will copy the variable, </P> <p> STD: cout <"before:" <shared_to_last_private <STD: Endl; </P> <p> # pragma OMP parallel for lastprivate (shared_to_last_private) firstprivate (shared_to_last_private) <br/> for (INT I = 0; I <11; + I) <br/>{< br/> STD: cout <++ shared_to_last_private <STD: Endl; <br/>}</P> <p> STD :: cout <"after:" <shared_to_last_private <STD: Endl; <br/> return 0; <br/>}< br/>
Similarly, you still need to use fristprivate to initialize the variables in the parallel zone. Otherwise, an error will occur.
Before and after running, the value of the shared_to_last_private variable changes, and the value finally changes to the value of the last loop, that is, the last modified shared_to_last_private (the copy of shared_to_last_private) of multiple threads) the value is assigned to shared_to_last_private.
VII. Shared example
# Include <iostream> <br/> # include <OMP. h> // header file to be included in OpenMP programming </P> <p> int main () <br/>{< br/> int sum = 0; </P> <p> STD: cout <"before:" <sum <STD: Endl; </P> <p> # pragma OMP parallel for shared (SUM) <br/> for (INT I = 0; I <10; ++ I) <br/>{< br/> sum + = I; <br/> STD: cout <sum <STD: Endl; <br/>}</P> <p> STD: cout <"after:" <sum <STD: Endl; <br/> return 0; <br/>}< br/>
AboveCodeIn, sum itself is shared. Here the shared statement is used as a demonstration.
In fact, there is still a problem with the above Code. Because sum is shared, the operations on sum by multiple threads will lead to data competition. We will introduce data competition in the future.
8. Section
Describes the usage of private, firstprivate, lastprivate, and shared.