在x86中增量是一个整数primefaces?

在多核x86机器上,假设在core1上执行的线程增加一个整数变量a ,同时核心2上的线程也增加它。 假设a的初始值为0,那么它最终总是2吗? 或者它可能有其他价值? 假设a被声明为volatile并且我们没有使用primefaces变量(例如C ++的atomic 和gcc中的原子操作)。

如果在这种情况下a的值确实总是2,那是否意味着x86-64中的long int也具有相同的属性,即a到底总是2?

只有在使用LOCK前缀时,X86上的increment-memory机器指令才是primefaces的。

C和C ++中的x ++没有primefaces行为。 如果你解锁增量,由于处理器正在读取和写入X的比赛,如果两个单独的处理器尝试增加,你最终只能看到一个增量或两者都被看到(第二个处理器可能已经读取了初始值,增加了它,并在第一次写回结果后写回来)。

我相信C ++ 11提供primefaces增量,并且大多数供应商编译器都有一种惯用的方法来导致某些内置整数类型(通常是int和long)的primefaces增量; 请参阅编译器参考手册。

如果要增加“大值”(例如,多精度整数),则需要使用一些标准锁定机制(如信号量)。

请注意,您还需要担心primefaces读取 。 在x86上,如果是64位字对齐,则读取32位或64位值恰好是primefaces的。 对于“大价值”而言,情况并非如此; 再次,你需要一些标准锁。

这是一个certificate它在特定实现(gcc)中不是primefaces的,如你所见(?),gcc生成的代码

  1. 将值从内存加载到寄存器
  2. 递增寄存器的内容
  3. 将寄存器保存回内存。

这离primefaces很远。

 $ cat tc volatile int a; void func(void) { a++; } [19:51:52 0 ~] $ gcc -O2 -c tc [19:51:55 0 ~] $ objdump -d to to: file format elf32-i386 Disassembly of section .text: 00000000 : 0: a1 00 00 00 00 mov 0x0,%eax 5: 83 c0 01 add $0x1,%eax 8: a3 00 00 00 00 mov %eax,0x0 d: c3 ret 

不要被mov指令中的0x0所欺骗,那里有4个字节的空间,并且链接器将填充此目标文件链接时的结果内存地址。

既然没有人回答你的实际问题,而是以一种始终有效的方式向你展示如何做到这一点:

线程1加载值0

线程2加载值0

线程1递增商店1

线程2递增其本地寄存器值的值并存储1。

正如您所看到的,最终结果是一个等于1而不是2的值。最后它不会总是2。

这不保证。 您可以使用lock xadd指令来实现相同的效果,或者使用C ++ std::atomic ,或者使用#pragma omp atomic ,或者使用已编写的任何其他并发解决方案来节省重新发明轮子的麻烦。