原子操作及对C++编程的意义
来源:互联网 发布:php培训机构达内教育 编辑:程序博客网 时间:2024/04/25 06:53
前言
所谓原子操作,就是“不可中断的一个或一系列操作”。
在对称多处理器(Symmetric Multi-Processor)结构中就不同了,由于系统中有多个处理器在独立地运行,即使能在单条指令中完成的操作也有可能受到干扰。
CPU对原子操作的影响
intel处理器
《Intel 64 and IA-32 Architectures Software Developer`s Manual》Volume3 System Programming Guide,8.1.1 Guaranteed Atomic Operations中讲解的原子操作如下:
Reading or writing a byte
读写一个byte
Reading or writing a word aligned on a 16-bit boundary
读写16bit(2byte)内存对齐的字(word)
Reading or writing a doubleword aligned on a 32-bit boundary
读写32bit(4byte)内存对齐的双字(dword)
The Pentium processor (and newer processors since) guarantees that the following additional memory operationswill always be carried out atomically:
Pentium系列处理器(以及以后生产的处理器)确保以下对基本存储器的操作行为为原子操作:
Reading or writing a quadword aligned on a 64-bit boundary
读写64bit(8byte)内存对齐的四字(quadword)
16-bit accesses to uncached memory locations that fit within a 32-bit data bus
使用16bit访问的未缓存的内存,并且这些内存适应32位数据总线(翻译不好)
The P6 family processors (and newer processors since) guarantee that the following additional memory operationwill always be carried out atomically:
P6系列处理器(以及以后生产的处理器)确保以下对基本存储器的操作行为为原子操作:
Unaligned 16-, 32-, and 64-bit accesses to cached memory that fit within a cache line
对单个cache line中缓存地址的未对齐的16/32/64位访问(非对齐的数据访问非常影响性能)
Accesses to cacheable memory that are split across cache lines and page boundaries are not guaranteed to beatomic by the Intel Core 2 Duo, Intel®Atom™, Intel Core Duo, Pentium M, Pentium 4, Intel Xeon, P6 family, Pentium, and Intel486 processors. The Intel Core 2 Duo, Intel Atom, Intel Core Duo, Pentium M, Pentium 4, IntelXeon, and P6 family processors provide bus control signals that permit external memory subsystems to make splitaccesses atomic; however, nonaligned data accesses will seriously impact the performance of the processor andshould be avoided.
那些被总线带宽、cache line以及page大小给分隔开了的内存地址的访问不是原子的,你如果想保证这些操作是原子的,你就得求助于机制Bus Lock,对总线发出相应的控制信号才行。
An x87 instruction or an SSE instructions that accesses data larger than a quadword may be implemented usingmultiple memory accesses. If such an instruction stores to memory, some of the accesses may complete (writingto memory) while another causes the operation to fault for architectural reasons (e.g. due an page-table entry thatis marked “not present”). In this case, the effects of the completed accesses may be visible to software eventhough the overall instruction caused a fault. If TLB invalidation has been delayed (see Section 4.10.4.4), suchpage faults may occur even if all accesses are to the same page.
在intel处理器上c++中一些基本的运算那些是基本操作?(本人CPU为Intel Core i5-4590 3.3GHz, x, y均为int型)
操作
反汇编代码(VS2010)
++imov eax,dword ptr [i]
add eax,1
mov dword ptr [i],eaxi++mov eax,dword ptr [i]
add eax,1
mov dword ptr [i],eaxx = ymov eax,dword ptr [y]
mov dword ptr [x],eaxx = 1mov dword ptr [x],1 x + ymov eax,dword ptr [x]
add eax,dword ptr [y]x + 1mov eax,dword ptr [x]
add eax,1x += ymov eax,dword ptr [x]
add eax,dword ptr [y]
mov dword ptr [x],eaxx += 1mov eax,dword ptr [x]
add eax,1
mov dword ptr [x],eax x - ymov eax,dword ptr [x]
sub eax,dword ptr [y] x - 1mov eax,dword ptr [x]
sub eax,1x -= ymov eax,dword ptr [x]
sub eax,dword ptr [y]
mov dword ptr [x],eaxx -= 1mov eax,dword ptr [x]
sub eax,1
mov dword ptr [x],eaxx * ymov eax,dword ptr [x]
imul eax,dword ptr [y]x * 10(x*1和x*2会被优化)mov eax,dword ptr [x]
imul eax,eax,0Ahx *= ymov eax,dword ptr [x]
imul eax,dword ptr [y]
mov dword ptr [x],eaxx *= 10mov eax,dword ptr [x]
imul eax,eax,0Ah
mov dword ptr [x],eaxx / ymov eax,dword ptr [x]
cdq
idiv eax,dword ptr [y]x / 10mov eax,dword ptr [x]
cdq
mov ecx,0Ah
idiv eax,ecx10 / xmov eax,0Ah
cdq
idiv eax,dword ptr [x]x /= ymov eax,dword ptr [x]
cdq
idiv eax,dword ptr [y]
mov dword ptr [x],eaxx /= 10mov eax,dword ptr [x]
cdq
mov ecx,0Ah
idiv eax,ecx
mov dword ptr [x],eaxx % ymov eax,dword ptr [x]
cdq
idiv eax,dword ptr [y]x % 10mov eax,dword ptr [x]
cdq
mov ecx,0Ah
idiv eax,ecxx %= ymov eax,dword ptr [x]
cdq
idiv eax,dword ptr [y]
mov dword ptr [x],edxx %= 10mov eax,dword ptr [x]
cdq
mov ecx,0Ah
idiv eax,ecx
mov dword ptr [x],edxx >> ymov eax,dword ptr [x]
mov ecx,dword ptr [y]
sar eax,clx >> 1mov eax,dword ptr [x]
sar eax,1x << ymov eax,dword ptr [x]
mov ecx,dword ptr [y]
shl eax,clx << 1mov eax,dword ptr [x]
shl eax,1x >>= ymov eax,dword ptr [x]
mov ecx,dword ptr [y]
sar eax,cl
mov dword ptr [x],eaxx >>= 1mov eax,dword ptr [x]
sar eax,1
mov dword ptr [x],eaxx <<= ymov eax,dword ptr [x]
mov ecx,dword ptr [y]
shl eax,cl
mov dword ptr [x],eaxx <<= 1mov eax,dword ptr [x]
shl eax,1
mov dword ptr [x],eaxx & ymov eax,dword ptr [x]
and eax,dword ptr [y]x & 10mov eax,dword ptr [x]
and eax,0Ahx &= ymov eax,dword ptr [x]
and eax,dword ptr [y]
mov dword ptr [x],eaxx &= 10mov eax,dword ptr [x]
and eax,0Ah
mov dword ptr [x],eaxx | ymov eax,dword ptr [x]
or eax,dword ptr [y] x | 10mov eax,dword ptr [x]
or eax,0Ahx |= ymov eax,dword ptr [x]
or eax,dword ptr [y]
mov dword ptr [x],eaxx |= 10mov eax,dword ptr [x]
or eax,0Ah
mov dword ptr [x],eaxx ^ ymov eax,dword ptr [x]
xor eax,dword ptr [y] x ^ 10mov eax,dword ptr [x]
xor eax,0Ahx ^= ymov eax,dword ptr [x]
xor eax,dword ptr [y]
mov dword ptr [x],eaxx ^= 10mov eax,dword ptr [x]
xor eax,0Ah
mov dword ptr [x],eax!xxor eax,eax
cmp dword ptr [x],0
sete al~xmov eax,dword ptr [x]
not eax从图表中看出就 x = 1为一条汇编操作指令。那我们再来看下不同类型下的的值为x赋值的结果:
类型反汇编代码(vs2010)char x = 10;mov byte ptr [x],0Ahunsigned char x = 10;mov byte ptr [x],0Ahshort x = 10;mov eax,0Ah
mov word ptr [x],axunsigned short x = 10;mov eax,0Ah
mov word ptr [x],axint x = 10;mov dword ptr [x],0Ahunsigned int x = 10;mov dword ptr [x],0Ahlong x = 10;mov dword ptr [x],0Ahunsigned long x = 10;mov dword ptr [x],0Ahlong long x = 0xFFFFFFFFFFFF;mov dword ptr [x],0FFFFFFFFh
mov dword ptr [ebp-8],0FFFFhunsigned long long x = 0xFFFFFFFFFFFF;mov dword ptr [x],0FFFFFFFFh
mov dword ptr [ebp-8],0FFFFhfloat x = 10.20;fld dword ptr [__real@41233333 (0F6311Ch)]
fstp dword ptr [x]double x = 10.20;fld qword ptr [__real@4024666666666666 (13D3120h)]
fstp qword ptr [x]__int8 x = 10;
mov byte ptr [x],0Ah
__int16 x = 10;
mov eax,0Ah
mov word ptr [x],ax
__int32 x = 10;
mov dword ptr [x],0Ah
__int64 x = 0xFFFFFFFFFFFF;
mov dword ptr [x],0FFFFFFFFh
mov dword ptr [ebp-8],0FFFFh
C++中线程同步
什么情况需要线程同步
1、有两个或两个以上的线程对同一份数进行操作,而且这些线程中存在写操作。
2、每个线程对该数据的操作完成后才能进行其他线程对该数据的操作,也就是乱序会对数据产生”撕裂“或数据难以预料。
比如说一个结构体重有两个成员变量{int x; int y;}, 如果一个线程对该结构体的实例进行写操作{x = 1, y = 2},另一个也进行写操作{x = 3, y = 4};如果没有进行线程同步,会存在如下几种情况:
x = 1y =2x = 1y =4x = 3y =2x = 3y = 4这样会造成数据的”撕裂“,从而需要我们进行线程同步保证数据要么是{x = 1, y = 2},要么是{x = 3, y = 4}。
在C++中面对内建类型的多线程同步,非原子操作并不一定需要线程同步
说明
同步?
++imov eax,dword ptr [i]
add eax,1
mov dword ptr [i],eax存在对同一数据的读写, 乱序会造成数据异常需要i++mov eax,dword ptr [i]
add eax,1
mov dword ptr [i],eax同上需要x = ymov eax,dword ptr [y]
mov dword ptr [x],eax非对同一数据的读写,而且乱序不会对数据结果产生影响不需要x = 1mov dword ptr [x],1 本来就是原子操作不需要x + ymov eax,dword ptr [x]
add eax,dword ptr [y]x + y不赋值给其他变量是没有意义的,不做讨论 x + 1mov eax,dword ptr [x]
add eax,1不赋值给其他变量是没有意义的,不做讨论 x += ymov eax,dword ptr [x]
add eax,dword ptr [y]
mov dword ptr [x],eax存在对同一数据的读写, 乱序会造成数据异常需要x += 1mov eax,dword ptr [x]
add eax,1
mov dword ptr [x],eax 存在对同一数据的读写, 乱序会造成数据异常需要x - ymov eax,dword ptr [x]
sub eax,dword ptr [y] 不赋值给其他变量是没有意义的,不做讨论 x - 1mov eax,dword ptr [x]
sub eax,1不赋值给其他变量是没有意义的,不做讨论 x -= ymov eax,dword ptr [x]
sub eax,dword ptr [y]
mov dword ptr [x],eax存在对同一数据的读写, 乱序会造成数据异常需要x -= 1mov eax,dword ptr [x]
sub eax,1
mov dword ptr [x],eax存在对同一数据的读写, 乱序会造成数据异常需要x * ymov eax,dword ptr [x]
imul eax,dword ptr [y]不赋值给其他变量是没有意义的,不做讨论 x * 10(x*1和x*2会被优化)mov eax,dword ptr [x]
imul eax,eax,0Ah不赋值给其他变量是没有意义的,不做讨论 x *= ymov eax,dword ptr [x]
imul eax,dword ptr [y]
mov dword ptr [x],eax存在对同一数据的读写, 乱序会造成数据异常需要x *= 10mov eax,dword ptr [x]
imul eax,eax,0Ah
mov dword ptr [x],eax存在对同一数据的读写, 乱序会造成数据异常需要x / ymov eax,dword ptr [x]
cdq
idiv eax,dword ptr [y]不赋值给其他变量是没有意义的,不做讨论 x / 10mov eax,dword ptr [x]
cdq
mov ecx,0Ah
idiv eax,ecx不赋值给其他变量是没有意义的,不做讨论 10 / xmov eax,0Ah
cdq
idiv eax,dword ptr [x]不赋值给其他变量是没有意义的,不做讨论 x /= ymov eax,dword ptr [x]
cdq
idiv eax,dword ptr [y]
mov dword ptr [x],eax存在对同一数据的读写, 乱序会造成数据异常需要x /= 10mov eax,dword ptr [x]
cdq
mov ecx,0Ah
idiv eax,ecx
mov dword ptr [x],eax存在对同一数据的读写, 乱序会造成数据异常需要x % ymov eax,dword ptr [x]
cdq
idiv eax,dword ptr [y]不赋值给其他变量是没有意义的,不做讨论 x % 10mov eax,dword ptr [x]
cdq
mov ecx,0Ah
idiv eax,ecx不赋值给其他变量是没有意义的,不做讨论 x %= ymov eax,dword ptr [x]
cdq
idiv eax,dword ptr [y]
mov dword ptr [x],edx存在对同一数据的读写, 乱序会造成数据异常需要x %= 10mov eax,dword ptr [x]
cdq
mov ecx,0Ah
idiv eax,ecx
mov dword ptr [x],edx存在对同一数据的读写, 乱序会造成数据异常需要x >> ymov eax,dword ptr [x]
mov ecx,dword ptr [y]
sar eax,cl不赋值给其他变量是没有意义的,不做讨论 x >> 1mov eax,dword ptr [x]
sar eax,1不赋值给其他变量是没有意义的,不做讨论 x << ymov eax,dword ptr [x]
mov ecx,dword ptr [y]
shl eax,cl不赋值给其他变量是没有意义的,不做讨论 x << 1mov eax,dword ptr [x]
shl eax,1不赋值给其他变量是没有意义的,不做讨论 x >>= ymov eax,dword ptr [x]
mov ecx,dword ptr [y]
sar eax,cl
mov dword ptr [x],eax存在对同一数据的读写, 乱序会造成数据异常需要x >>= 1mov eax,dword ptr [x]
sar eax,1
mov dword ptr [x],eax存在对同一数据的读写, 乱序会造成数据异常需要x <<= ymov eax,dword ptr [x]
mov ecx,dword ptr [y]
shl eax,cl
mov dword ptr [x],eax存在对同一数据的读写, 乱序会造成数据异常需要x <<= 1mov eax,dword ptr [x]
shl eax,1
mov dword ptr [x],eax存在对同一数据的读写, 乱序会造成数据异常需要x & ymov eax,dword ptr [x]
and eax,dword ptr [y]不赋值给其他变量是没有意义的,不做讨论 x & 10mov eax,dword ptr [x]
and eax,0Ah不赋值给其他变量是没有意义的,不做讨论 x &= ymov eax,dword ptr [x]
and eax,dword ptr [y]
mov dword ptr [x],eax存在对同一数据的读写, 乱序会造成数据异常需要x &= 10mov eax,dword ptr [x]
and eax,0Ah
mov dword ptr [x],eax存在对同一数据的读写, 乱序会造成数据异常需要x | ymov eax,dword ptr [x]
or eax,dword ptr [y] 不赋值给其他变量是没有意义的,不做讨论 x | 10mov eax,dword ptr [x]
or eax,0Ah不赋值给其他变量是没有意义的,不做讨论 x |= ymov eax,dword ptr [x]
or eax,dword ptr [y]
mov dword ptr [x],eax存在对同一数据的读写, 乱序会造成数据异常需要x |= 10mov eax,dword ptr [x]
or eax,0Ah
mov dword ptr [x],eax存在对同一数据的读写, 乱序会造成数据异常需要x ^ ymov eax,dword ptr [x]
xor eax,dword ptr [y] 不赋值给其他变量是没有意义的,不做讨论 x ^ 10mov eax,dword ptr [x]
xor eax,0Ah不赋值给其他变量是没有意义的,不做讨论 x ^= ymov eax,dword ptr [x]
xor eax,dword ptr [y]
mov dword ptr [x],eax存在对同一数据的读写, 乱序会造成数据异常需要x ^= 10mov eax,dword ptr [x]
xor eax,0Ah
mov dword ptr [x],eax存在对同一数据的读写, 乱序会造成数据异常需要!xxor eax,eax
cmp dword ptr [x],0
sete al不赋值给其他变量是没有意义的,不做讨论 ~xmov eax,dword ptr [x]
not eax不赋值给其他变量是没有意义的,不做讨论
对内建类型变量的赋值(数值):
类型反汇编代码(vs2010)说明
同步?
char x = 10;mov byte ptr [x],0Ah原子操作不需要unsigned char x = 10;mov byte ptr [x],0Ah原子操作不需要short x = 10;mov eax,0Ah
mov word ptr [x],ax只有一个写操作不需要unsigned short x = 10;mov eax,0Ah
mov word ptr [x],ax只有一个写操作不需要int x = 10;mov dword ptr [x],0Ah原子操作不需要unsigned int x = 10;mov dword ptr [x],0Ah原子操作不需要long x = 10;mov dword ptr [x],0Ah原子操作不需要unsigned long x = 10;mov dword ptr [x],0Ah原子操作不需要long long x = 0xFFFFFFFFFFFF;mov dword ptr [x],0FFFFFFFFh
mov dword ptr [ebp-8],0FFFFh写写操作需要unsigned long long x = 0xFFFFFFFFFFFF;mov dword ptr [x],0FFFFFFFFh
mov dword ptr [ebp-8],0FFFFh写写操作需要float x = 10.20;fld dword ptr [__real@41233333 (0F6311Ch)]
fstp dword ptr [x]只有一个写操作不需要double x = 10.20;fld qword ptr [__real@4024666666666666 (13D3120h)]
fstp qword ptr [x]只有一个写操作不需要__int8 x = 10;
mov byte ptr [x],0Ah
原子操作不需要__int16 x = 10;
mov eax,0Ah
mov word ptr [x],ax
只有一个写操作不需要__int32 x = 10;
mov dword ptr [x],0Ah
原子操作不需要__int64 x = 0xFFFFFFFFFFFF;
mov dword ptr [x],0FFFFFFFFh
mov dword ptr [ebp-8],0FFFFh
写写操作需要
对内建类型变量的赋值(变量):
类型反汇编代码(vs2010)说明
同步?
char x = y;mov al,byte ptr [y]
mov byte ptr [x],al非对同一数据的读写,而且乱序不会对数据结果产生影响不需要unsigned char x = y;mov al,byte ptr [y]
mov byte ptr [x],al非对同一数据的读写,而且乱序不会对数据结果产生影响不需要short x = y;mov ax,word ptr [y]
mov word ptr [x],ax非对同一数据的读写,而且乱序不会对数据结果产生影响不需要unsigned short x = y;mov ax,word ptr [y]
mov word ptr [x],a非对同一数据的读写,而且乱序不会对数据结果产生影响不需要int x = y;mov eax,dword ptr [y]
mov dword ptr [x],eax非对同一数据的读写,而且乱序不会对数据结果产生影响不需要unsigned int x = y;mov eax,dword ptr [y]
mov dword ptr [x],eax非对同一数据的读写,而且乱序不会对数据结果产生影响不需要long x = y;mov eax,dword ptr [y]
mov dword ptr [x],eax非对同一数据的读写,而且乱序不会对数据结果产生影响不需要unsigned long x = y;mov eax,dword ptr [y]
mov dword ptr [x],eax非对同一数据的读写,而且乱序不会对数据结果产生影响不需要long long x = y;mov eax,dword ptr [y]
mov dword ptr [x],eax
mov ecx,dword ptr [ebp-18h]
mov dword ptr [ebp-8],ecx对x存在写写操作,乱序会产出数据”撕裂“需要unsigned long long x = y;mov eax,dword ptr [y]
mov dword ptr [x],eax
mov ecx,dword ptr [ebp-18h]
mov dword ptr [ebp-8],ecx对x存在写写操作,乱序会产出数据”撕裂“需要float x = y;fld dword ptr [y]
fstp dword ptr [x]非对同一数据的读写,而且乱序不会对数据结果产生影响不需要double x = y;fld qword ptr [y]
fstp qword ptr [x]非对同一数据的读写,而且乱序不会对数据结果产生影响不需要__int8 x = y;
mov al,byte ptr [y]
mov byte ptr [x],al
非对同一数据的读写,而且乱序不会对数据结果产生影响不需要__int16 x =y;
mov ax,word ptr [y]
mov word ptr [x],ax
非对同一数据的读写,而且乱序不会对数据结果产生影响不需要__int32 x =y;
mov eax,dword ptr [y]
mov dword ptr [x],eax
非对同一数据的读写,而且乱序不会对数据结果产生影响不需要__int64 x = y;
mov eax,dword ptr [y]
mov dword ptr [x],eax
mov ecx,dword ptr [ebp-18h]
mov dword ptr [ebp-8],ecx
需要
0 0
- 原子操作及对C++编程的意义
- 原子操作及函数
- 对图像进行卷积操作的意义!
- 编程能力对测试人员的意义
- [转]c++: fstream文件操作及对二进制文件的操作
- C/C++-------------__sync_fetch_and_add 原子操作------------------
- Java中对非原子的64位操作
- 一种基于JavaScript原子部分的深奥而有教育意义的编程风格
- 位操作的意义及高效性
- linux编程之原子操作
- 并发编程之原子操作
- 原子操作及线程同步
- Linux原子操作及函数
- 原子操作及线程同步
- java并发编程学习(四) 原子操作的实现原理
- [C++]gcc中的原子操作
- WINCE的原子操作
- 互锁的原子操作
- JavaScript__JavaScript中的匿名函数及函数的闭包
- innerHTML
- 如何检测硬盘坏道
- 搭建pcduino交叉编译环境
- Nginx下搭建Nagios
- 原子操作及对C++编程的意义
- AVPlayer介绍
- Lytro转行挺进 虚拟现实领域 推出Immerge相机
- 设计算法1
- Mac OSX10.11更新后sudo竟然不能写/bin,/usr/bin /usr/sbin等系统目录了。
- Firebase 特性翻译
- textview多行文本后加上图片
- eq,neq,gt,lt等表达式缩写
- hdu 2844 Coins(多重背包)