制造“原子”的东西本质上只是一种锁机制吗?

时间:2021-03-06 13:51:06

From the OpenMP summary pdf: "operation ensures that a specific storage location is updated atomically". This brough up the question for me what "atomic" is and wheter it is just a lock mechanism. So if I remember correctly "atomic" means that some hardware support is built in to prevent anything else from changing the value. So is making something "atomic" essentially just implementing a lock mechanism or is it something more?

从OpenMP摘要pdf:“操作确保特定存储位置以原子方式更新”。这为我提出了一个问题,即“原子”是什么,而它只是一个锁定机制。因此,如果我没记错,“原子”意味着内置一些硬件支持以防止其他任何内容更改值。那么制造一些“原子”基本上只是实现一种锁定机制还是更多的东西呢?

2 个解决方案

#1


1  

I think there might be some confusion around "atomicity" vs "isolation". They're similar concepts, but there is a subtle difference between them. Atomicity means that an operation either completes entirely, or not at all. Isolation guarantees that operations that happen concurrently result in a state that could have been caused by them executing serially.

我认为围绕“原子性”与“孤立性”可能存在一些混淆。它们是类似的概念,但它们之间存在细微差别。原子性意味着操作要么完全完成,要么根本不完成。隔离保证同时发生的操作导致可能由它们串行执行的状态。

For example, if the operation is "add 1 to x, then multiply x by 2", and x starts as 3, the result will be 3 if there is any sort of failure, or 8 if there is not. Even if the power cuts out right after 1 is added, the result when you reboot is guaranteed to be 3.

例如,如果操作是“将x加1,则将x乘以2”,x开始为3,如果存在任何类型的失败,结果将为3,否则为8。即使在添加1后立即切断电源,重启时的结果也保证为3。

Now consider what happens if this operation is performed twice, concurrently. Both could fail, resulting in x=3. One could fail, x=8. Both could succeed, x=18. If we are guaranteed isolation, these are the only outcomes. But, if we are only given atomicity, not isolation, a fourth outcome could happen, wherein the individual parts are interleaved as "add 1, add 1, multiply by 2, multiply by 2", resulting in x=20!

现在考虑如果同时执行此操作两次会发生什么。两者都可能失败,导​​致x = 3。一个人可能会失败,x = 8。两者都可以成功,x = 18。如果我们保证隔离,这些是唯一的结果。但是,如果我们只给出原子性而不是隔离,则可能发生第四种结果,其中各个部分交错为“加1,加1,乘2,乘2”,得到x = 20!

If you're guaranteed only isolation, but not atomicity, you could end up with x=3, 4, 5, 8, 10, or 18.

如果你只保证隔离,而不是原子性,你最终可能会得到x = 3,4,5,8,10或18。

With all that said, this is a common misconception, and often when people say "atomicity" they mean both. That's my suspicion of what they mean in the OpenMP documentation.

尽管如此,这是一种常见的误解,通常当人们说“原子性”时,它们都意味着两者。这是我怀疑它们在OpenMP文档中的含义。

#2


0  

Updating a value stored in memory is a three-step process. First the value is fetched from memory and brought to one of the CPU's registers. Then, the value in the register is changed in some way (say incremented). Finally, the new value is written back to memory so that it can be used again.

更新存储在内存中的值分为三个步骤。首先,从内存中获取值并将其带到CPU的一个寄存器中。然后,寄存器中的值以某种方式改变(例如递增)。最后,将新值写回内存,以便可以再次使用。

Doing this (or any other) operation atomically simply means that all three of those steps happen, or none of them does.

原子地执行此(或任何其他)操作只是意味着所有这三个步骤都发生,或者没有一个步骤发生。

It only becomes interesting or important when you have another thread or process that also needs to use that same memory value. Suppose both want to increment the value, which is initially zero. Without atomic operations, the second thread might read the original value (0) from memory even as the first thread is incrementing it in a register. Effectively both threads may see the value 0, increment it to 1, and return it to memory. At the end of this sequence, the value in memory would be 1 despite having been incremented twice.

只有当另一个线程或进程也需要使用相同的内存值时,它才会变得有趣或重要。假设两者都想增加该值,该值最初为零。没有原子操作,第二个线程可能会从内存中读取原始值(0),即使第一个线程正在寄存器中递增它。实际上,两个线程都可以看到值0,将其增加到1,然后将其返回到内存。在此序列结束时,尽管已增加两次,但内存中的值仍为1。

With an atomic increment operation, there is no way that that sequence can occur. Once the first thread enters the atomic sequence, there is no way the second thread can read the value in memory before the first thread has incremented it and written it back to memory. You'll always get the correct value (2).

使用原子递增操作,无法发生该序列。一旦第一个线程进入原子序列,第二个线程就无法在第一个线程增加它并将其写回内存之前读取内存中的值。你总能得到正确的值(2)。

So, to answer your question, it's almost like a lock mechanism. In particular, it's like a lock mechanism exists around whatever the original operation was. Atomic operations themselves are frequently used in the implementation of other locking mechanisms, such as mutexes and semaphores.

所以,要回答你的问题,它几乎就像一个锁定机制。特别是,它就像一个锁定机制存在于原始操作周围。原子操作本身经常用于实现其他锁定机制,例如互斥锁和信号量。

#1


1  

I think there might be some confusion around "atomicity" vs "isolation". They're similar concepts, but there is a subtle difference between them. Atomicity means that an operation either completes entirely, or not at all. Isolation guarantees that operations that happen concurrently result in a state that could have been caused by them executing serially.

我认为围绕“原子性”与“孤立性”可能存在一些混淆。它们是类似的概念,但它们之间存在细微差别。原子性意味着操作要么完全完成,要么根本不完成。隔离保证同时发生的操作导致可能由它们串行执行的状态。

For example, if the operation is "add 1 to x, then multiply x by 2", and x starts as 3, the result will be 3 if there is any sort of failure, or 8 if there is not. Even if the power cuts out right after 1 is added, the result when you reboot is guaranteed to be 3.

例如,如果操作是“将x加1,则将x乘以2”,x开始为3,如果存在任何类型的失败,结果将为3,否则为8。即使在添加1后立即切断电源,重启时的结果也保证为3。

Now consider what happens if this operation is performed twice, concurrently. Both could fail, resulting in x=3. One could fail, x=8. Both could succeed, x=18. If we are guaranteed isolation, these are the only outcomes. But, if we are only given atomicity, not isolation, a fourth outcome could happen, wherein the individual parts are interleaved as "add 1, add 1, multiply by 2, multiply by 2", resulting in x=20!

现在考虑如果同时执行此操作两次会发生什么。两者都可能失败,导​​致x = 3。一个人可能会失败,x = 8。两者都可以成功,x = 18。如果我们保证隔离,这些是唯一的结果。但是,如果我们只给出原子性而不是隔离,则可能发生第四种结果,其中各个部分交错为“加1,加1,乘2,乘2”,得到x = 20!

If you're guaranteed only isolation, but not atomicity, you could end up with x=3, 4, 5, 8, 10, or 18.

如果你只保证隔离,而不是原子性,你最终可能会得到x = 3,4,5,8,10或18。

With all that said, this is a common misconception, and often when people say "atomicity" they mean both. That's my suspicion of what they mean in the OpenMP documentation.

尽管如此,这是一种常见的误解,通常当人们说“原子性”时,它们都意味着两者。这是我怀疑它们在OpenMP文档中的含义。

#2


0  

Updating a value stored in memory is a three-step process. First the value is fetched from memory and brought to one of the CPU's registers. Then, the value in the register is changed in some way (say incremented). Finally, the new value is written back to memory so that it can be used again.

更新存储在内存中的值分为三个步骤。首先,从内存中获取值并将其带到CPU的一个寄存器中。然后,寄存器中的值以某种方式改变(例如递增)。最后,将新值写回内存,以便可以再次使用。

Doing this (or any other) operation atomically simply means that all three of those steps happen, or none of them does.

原子地执行此(或任何其他)操作只是意味着所有这三个步骤都发生,或者没有一个步骤发生。

It only becomes interesting or important when you have another thread or process that also needs to use that same memory value. Suppose both want to increment the value, which is initially zero. Without atomic operations, the second thread might read the original value (0) from memory even as the first thread is incrementing it in a register. Effectively both threads may see the value 0, increment it to 1, and return it to memory. At the end of this sequence, the value in memory would be 1 despite having been incremented twice.

只有当另一个线程或进程也需要使用相同的内存值时,它才会变得有趣或重要。假设两者都想增加该值,该值最初为零。没有原子操作,第二个线程可能会从内存中读取原始值(0),即使第一个线程正在寄存器中递增它。实际上,两个线程都可以看到值0,将其增加到1,然后将其返回到内存。在此序列结束时,尽管已增加两次,但内存中的值仍为1。

With an atomic increment operation, there is no way that that sequence can occur. Once the first thread enters the atomic sequence, there is no way the second thread can read the value in memory before the first thread has incremented it and written it back to memory. You'll always get the correct value (2).

使用原子递增操作,无法发生该序列。一旦第一个线程进入原子序列,第二个线程就无法在第一个线程增加它并将其写回内存之前读取内存中的值。你总能得到正确的值(2)。

So, to answer your question, it's almost like a lock mechanism. In particular, it's like a lock mechanism exists around whatever the original operation was. Atomic operations themselves are frequently used in the implementation of other locking mechanisms, such as mutexes and semaphores.

所以,要回答你的问题,它几乎就像一个锁定机制。特别是,它就像一个锁定机制存在于原始操作周围。原子操作本身经常用于实现其他锁定机制,例如互斥锁和信号量。