一般地,对于int num
,num++
(或++num
),作为读-修改-写操作中,是不是原子.但我经常看到编译器,例如GCC,为它生成以下代码(在这里尝试):
由于第5行对应于num++
一条指令,我们可以得出结论,在这种情况下num++
是原子的吗?
如果是这样,是否意味着如此生成num++
可以在并发(多线程)场景中使用而没有任何数据争用的危险(例如,我们不需要制作它,std::atomic<int>
并强加相关成本,因为它是无论如何原子)?
UPDATE
请注意,这个问题不是增量是否是原子的(它不是,而且是问题的开头行).它是否可以在特定场景中,即在某些情况下是否可以利用单指令性质来避免lock
前缀的开销.而且,作为公认的答案约单处理器的机器,还有部分提到这个答案,在其评论和其他人谈话解释,它可以(尽管不是C或C++).
如果MESI协议阻止其他内核写入"独占"拥有的数据,那么x86 LOCK前缀的目的是什么?
我对LOCK提供的内容和MESI提供的内容感到有些困惑?
我理解MESI协议是关于确保内核都看到一致的内存状态,但据我所知,它还可以防止内核写入另一个内核已经写入的内存?
我最近看到一些关于使用原子增量/负载实现的计数器与使用互斥量来同步增量/负载的计数器之间是否存在差异的一些讨论.
以下计数器实现在功能上是否相同?
type Counter interface {
Inc()
Load() int64
}
// Atomic Implementation
type AtomicCounter struct {
counter int64
}
func (c *AtomicCounter) Inc() {
atomic.AddInt64(&c.counter, 1)
}
func (c *AtomicCounter) Load() int64 {
return atomic.LoadInt64(&c.counter)
}
// Mutex Implementation
type MutexCounter struct {
counter int64
lock sync.Mutex
}
func (c *MutexCounter) Inc() {
c.lock.Lock()
defer c.lock.Unlock()
c.counter++
}
func (c *MutexCounter) Load() int64 {
c.lock.Lock()
defer c.lock.Unlock()
return c.counter
}
Run Code Online (Sandbox Code Playgroud)
我运行了一堆测试用例(Playground Link)并且无法看到任何不同的行为.在我的机器上运行测试时,所有PrintAll
测试功能都会无序打印数字.
有人可以确认它们是否相同或者是否存在不同的边缘情况?是否优先使用一种技术而不是另一种?该原子文档不说,它应该只在特殊情况下使用. …
我对互斥体的工作原理感兴趣.我了解他们的目的,因为我找到的每个网站都解释了他们的所作所为,但我无法理解在这种情况下会发生什么:
有两个线程同时运行,它们试图同时锁定互斥锁.
这在单核上不会出现问题,因为这种情况永远不会发生,但在多核系统中,我认为这是一个问题.我看不出有任何方法可以防止这样的并发问题,但它们显然存在.
谢谢你的帮助
我目前正与另一位开发人员辩论,他向我保证以下c ++语句是原子的:
x |= 0x1; // x is shared by multiple threads
Run Code Online (Sandbox Code Playgroud)
在发布模式下使用VC++ 11编译,会生成以下组合:
01121270 or dword ptr ds:[1124430h],1
Run Code Online (Sandbox Code Playgroud)
另一个开发人员说位操作是原子的,因此线程安全.我对intel i7处理器的体验另有说法.
我认为使用多核处理器时,由于各个处理器缓存,任何共享内存写入都是不安全的.但是,经过更多的研究,似乎x86处理器提供了与处理器/内核之间的内存操作顺序相关的一些保证,这表明它应该是安全的......再次,我的情况似乎并非如此.经验.
由于我对这些事情没有权威性的知识,所以我很难说出我的理由,甚至不相信我是对的.
当我使用x86_64 CAS指令时LOCK CMPXCHG
,即原子(读取值,比较并写回结果),此时锁定的内容:
这是真的吗,x86_64 Intel CPU使用?
concurrency multithreading x86-64 compare-and-swap cpu-cache
我正在尝试在我的代码中实现一个自旋锁,但是我基于Wikipedia实现的自旋锁导致了极慢的性能.
int lockValue = 0;
void lock() {
__asm__("loop: \n\t"
"movl $1, %eax \n\t"
"xchg %eax, lockValue \n\t"
"test %eax, %eax \n\t"
"jnz loop");
}
Run Code Online (Sandbox Code Playgroud)
有没有办法改善这一点,使其更快?
谢谢.