I. If you simply solve the read and write concurrency problem for shared resources in multi-threading, just use C + +: Thread class threads, atomic data class templates atomic<t> T, mutex mutex, lock lock, condition variable Condition_var Iables.two. Based on this, if you want to be in parallel programming or better performance, especially when using some weak memory order platform (such as PowerPC), it is necessary to set the memory order between atomic operations.C++11 joins the atomic Operation module, which supports parallel programming, and all atomic operations have a parameter memory_order.1. Introduction to the memory modelThe memory model is a hardware concept that indicates the order in which the machine instructions are executed by the processor (modern processors are not instruction-by-process machines).
1#include <thread>2#include <atomic>3 4atomic<int>A;5atomic<int>b;6 voidThreadhandle ()7 {8 intt =1;9A =T;Tenb =2; One}
In the three lines of code in the above thread-handling function, the actual order of execution in the register may be inconsistent with the order in which the code is written. Under different machine platforms, the processor may optimize the order of execution of the instruction cycle (multiple instructions for a clock cycle), that is, it may let B's assignment statement be executed first.
At this point, if a thread is looping through the values of a and B, then the result is not always a = = 1 and b = = 2.
2. How to ensure the order of instruction execution
The strongly sequential memory model refers to the fact that the code sequence is consistent with the order in which the registers are actually executed
A weak-order memory model refers to the fact that the order of the registers actually executes is inconsistent with the code order and is adjusted by the processor
3.c++ Parallel Programming: Specifying Instruction execution order
enum Memory_order { memory_order_relaxed, // do not guarantee memory_order_acquire of execution order, /// This thread, all subsequent read operations must be executed after the atomic operation of this section is completed , memory_order_release, /// in this thread, All previous write operations can be performed before this atomic operation Memory_order_acq_rel, // including both Memory_order_acquire and Memory_ Order_release memory_order_consume, // in this thread, all subsequent operations on this atomic type must be executed after the atomic operation of this article is completed memory_order_seq_cst // all accesses are executed sequentially } Memory_order;
Test: The following code may print a = = 0; b = = 2 results of this
1#include <iostream>2#include <thread>3#include <atomic>4 5atomic<int> a{0 };6atomic<int> b{0 };7 voidSetValue ()8 {9 intt =1;Ten A.store (t, memory_order_relaxed); OneB.store (2, memory_order_relaxed); A } - voidObserver () - { thecout << a << b <<Endl; - } - - intMain () + { -Thread T1 (SetValue,0); +Thread T2 (Observer,0); A at T1.join (); - T2.join (); - - return 0; -}
Three. For parallel programming, perhaps the most fundamental problem is how to break up a large number of computational problems into separate and simultaneous parts, and find the data that really needs to be shared between threads, and then implement atomic operations.
Memory model, C + + Memory_order