Use of volatile in C + +

Source: Internet
Author: User
Tags goto volatile

First, the role

The role of volatile is to ensure that this directive is not omitted due to compiler optimizations and requires each direct read value as a directive keyword.

In short, it prevents the compiler from optimizing the code. For example, the following programs:
xbyte[2]=0x55;
xbyte[2]=0x56;
xbyte[2]=0x57;
xbyte[2]=0x58;
For external hardware, the above four statements represent different operations, resulting in four different actions, but the compiler will optimize the above four statements, that only xbyte[2]=0x58 (that is, ignoring the first three statements, only one machine code). If you type volatile, the compiler compiles it one at a time and produces the corresponding machine code (producing four code).

Second, the meaning of volatile
Volatile is always about optimization, and the compiler has a technique calledData Flow Analysis, where variables in the parser are assigned, where they are used, where they are invalidated, analysis results can be used for constant merging, constant propagation and other optimizations, and further die code elimination. But sometimes these optimizations are not required by the program, you can use the volatile keyword to prohibit these optimizations, the literal meaning of volatile is variable, it has the following role:
1 The volatile variable is not cached in a register between two operations. In multi-tasking, interrupts, and even setjmp environments, variables can be changed by other programs, and the compiler cannot know for sure, and volatile is telling the compiler this is the case.
2 Do not do constant merging, constant propagation and other optimizations, so like the following code:
volatile int i = 1;
if (i > 0) ...
The IF condition is not treated as unconditional true.
3 reading and writing to volatile variables is not optimized. If you assign a value to a variable but it doesn't work, the compiler can often omit that assignment, but the processing of memory Mapped IO cannot be optimized.
Some people said that volatile can guarantee the atomic nature of memory operations, this is not accurate, one, x86 need lock prefix to ensure atomicity under the SMP, and second, RISC can not directly operate on the memory, to ensure that the atomicity of other methods, such as Atomic_inc.
For Jiffies, it has been declared as a volatile variable, and I think it is possible to use jiffies++ directly, and there is no need to use that complex form, because that does not guarantee atomicity.
You may not know that in Pentium and subsequent CPUs, the following two sets of instructions
Inc jiffies
;;
mov jiffies,%eax
Inc%eax
mov%eax, jiffies
function the same, but an instruction is not as fast as three instructions.
third, compiler optimization →C keyword volatile→memory break descriptor zz

"Memory" is very special, probably the most difficult part of the embedded assembly. To explain it clearly, first introduce the compiler's optimization knowledge, and then see the C keyword volatile. Finally, look at the descriptor.
1, compiler optimization Introduction
Memory access speed is far less than CPU processing speed, in order to improve the overall performance of the machine, the hardware to introduce hardware cache caches, speed up access to memory. In addition, the execution of instructions in the modern CPU is not necessarily executed in sequence, and no correlation instruction can be executed in order to make full use of the CPU's instruction pipeline and improve the execution speed. These are hardware-level optimizations. Look at software-level optimizations: One is optimized by programmers while writing code, and the other is optimized by the compiler. The commonly used methods of compiler optimizations are:caches memory variables to registers, and adjusts instruction sequences to take full advantage of CPU instruction pipelining, which is common in reordering read and write instructions. These optimizations are transparent and efficient when conventional memory is optimized. The solution to the problem caused by compiler optimizations or hardware reordering is to set the memory barrier between actions that must be performed in a particular order from the point of view of the hardware (or other processor), and Linux provides a macro to solve the compiler's order of execution issues.
void Barrier (void)
This function notifies the compiler to insert a memory barrier, but is not valid for the hardware, and the compiled code stores all the modified values in the current CPU register in memory, which is then re-read from memory when needed.
2. C keyword volatile
The C keyword volatile (note that it is used to modify variables instead of the __volatile__ described above) indicates that the values of a variable can be changed externally, so access to these variables cannot be cached to the register, which needs to be re-accessed each time it is used. This keyword is often used in multithreaded environments, because when you write multithreaded programs, the same variable can be modified by multiple threads, and the program synchronizes each thread through that variable, for example:
DWORD __stdcall ThreadFunc (LPVOID signal)
{
int* intsignal=reinterpret_cast<int*> (signal);
*intsignal=2;
while (*intsignal!=1)
Sleep (1000);
return 0;
}
The thread starts with intsignal set to 2, and then loops until intsignal exits 1 o'clock. It is obvious that the value of intsignal must be changed externally, otherwise the thread will not exit. However, the thread does not exit when it is actually running, even if it is externally changing its value to 1, look at the corresponding pseudo-assembly code to understand:
MOV ax,signal
Label
if (ax!=1)
Goto Label
For the C compiler, it does not know that this value will be modified by another thread. Naturally, it caches it in the register. Remember, the C compiler does not have a threading concept! This is where the use of volatile is needed. Volatile is intended to mean that this value may be changed outside the current thread. That is, we want to add the volatile keyword in front of the intsignal in ThreadFunc, when the compiler knows that the value of the variable changes externally, so each time the variable is accessed it is reread and the loop becomes as shown in the following pseudo-code:
Label
MOV ax,signal
if (ax!=1)
Goto Label
3. Memory
With the knowledge above it is not difficult to understand the memory modification descriptor, the memory descriptor tells GCC:
1) do not reorder the inline assembly instruction with the preceding instruction, that is, before executing the inline assembly code, the instructions before it are executed
2) do not cache variables to registers, because this code may use memory variables, and these memory variables will be changed in an unpredictable way, so gcc insert the necessary code to cache the value of the variables cached to the register back to memory, if the subsequent access to these variables, need to re-access memory.
If the assembly instruction modifies the memory, but GCC itself is not aware of, because in the output section is not described, it is necessary to add "memory" in the modification Description section, to tell the GCC memory has been modified, when GCC learned this information, will be before this command, Inserting the necessary instructions will first write back the values of the variables in the cache to the register, and then re-read them if they are to be used later.
This can also be achieved with "volatile", but instead of adding the keyword before each variable, it is easier to use "memory".

Reference article:

1, Http://baike.baidu.com/link?url=yMf2TWgeCi-7GzJzwdcHGwSA1XM-wrgPmxjb5TTDyVviLCziUJQ747BI384Pd7RaB5GZxRaMwhuuFkzwcaNit_

2, http://www.cnblogs.com/yc_sunniwell/archive/2010/06/24/1764231.html

Use of volatile in C + +

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.