做一件汇编指令总是以原子方式运行? [英] Does one assembler instruction always execute atomically?

查看:278
本文介绍了做一件汇编指令总是以原子方式运行?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

今天,我碰到这个问题就来了:

Today I came across this question:

你有code

static int counter = 0;
void worker() {
    for (int i = 1; i <= 10; i++)
        counter++;
}

如果工人将来自两个不同的线程调用,将计数有什么价值两个人后完成?

If worker would be called from two different threads, what value will counter have after both of them are finished?

我知道,其实它可以是任何东西。但是,我的内部胆量告诉我,那计数器++ 将最有可能被翻译成单一的汇编指令,如果两个线程都执行相同的核心,计数器将是20。

I know that actually it could be anything. But my internal guts tells me, that counter++ will most likely be translated into single assembler instruction, and if both threads are execute on the same core, counter will be 20.

但是,如果这些线程在不同内核或处理器上运行,莫不是在他们的微code的竞争条件?一个汇编指令总是可以被看作是原子操作?

But what if those threads are run on different cores or processors, could there be a race condition in their microcode? Is one assembler instruction could always be viewed as atomic operation?

推荐答案

专为X86,以及关于你的例子:计数器++ ,有许多方面,它可能是编译。最简单的例子是:

Specifically for x86, and regarding your example: counter++, there are a number of ways it could be compiled. The most trivial example is:

inc counter

此转换成以下的微操作:

This translates into the following micro operations:


  • 负荷计数来隐藏寄存器在CPU上

  • 增加寄存器

  • 存储在更新寄存器计数

  • load counter to a hidden register on the CPU
  • increment the register
  • store the updated register in counter

这在本质上是一样的:

mov eax, counter
inc eax
mov counter, eax

请注意,如果其他一些代理更新计数负载和存储之间,也不会在计数商店之后。这种试剂可以是在同一个芯另一个线程,在同一个CPU在另一个核心,在相同的系统中的另一个处理器,或甚至一些外部代理使用DMA(直接存储器存取)。

Note that if some other agent updates counter between the load and the store, it won't be reflected in counter after the store. This agent could be another thread in the same core, another core in the same CPU, another CPU in the same system, or even some external agent that uses DMA (Direct Memory Access).

如果你想保证这个 INC 是原子,使用锁定 preFIX:

If you want to guarantee that this inc is atomic, use the lock prefix:

lock inc counter

锁定保证没有人可以更新计数加载和存储之间。

lock guarantees that nobody can update counter between the load and the store.


对于更复杂的指令,通常不能假设他们会以原子方式运行的,除非他们支持锁定 preFIX。

Regarding more complicated instructions, you usually can't assume that they'll execute atomically, unless they support the lock prefix.

这篇关于做一件汇编指令总是以原子方式运行?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆