相关疑难解决方法(0)

num ++是'int num'的原子吗?

一般地,对于int num,num++(或++num),作为读-修改-写操作中,是不是原子.但我经常看到编译器,例如GCC,为它生成以下代码(在这里尝试):

在此输入图像描述

由于第5行对应于num++一条指令,我们可以得出结论,在这种情况下num++ 是原子的吗?

如果是这样,是否意味着如此生成num++可以在并发(多线程)场景中使用而没有任何数据争用的危险(例如,我们不需要制作它,std::atomic<int>并强加相关成本,因为它是无论如何原子)?

UPDATE

请注意,这个问题不是增量是否原子的(它不是,而且是问题的开头行).它是否可以在特定场景中,即在某些情况下是否可以利用单指令性质来避免lock前缀的开销.而且,作为公认的答案约单处理器的机器,还有部分提到这个答案,在其评论和其他人谈话解释,它可以(尽管不是C或C++).

c c++ assembly multithreading atomic

148
推荐指数
8
解决办法
1万
查看次数

LOCK前缀vs MESI协议?

如果MESI协议阻止其他内核写入"独占"拥有的数据,那么x86 LOCK前缀的目的是什么?

我对LOCK提供的内容和MESI提供的内容感到有些困惑?

我理解MESI协议是关于确保内核都看到一致的内存状态,但据我所知,它还可以防止内核写入另一个内核已经写入的内存?

cpu x86 multithreading locking mesi

8
推荐指数
2
解决办法
590
查看次数

使用原子操作的计数器和使用互斥锁的计数器之间的Go是否有区别?

我最近看到一些关于使用原子增量/负载实现的计数器与使用互斥量来同步增量/负载的计数器之间是否存在差异的一些讨论.

以下计数器实现在功能上是否相同?

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测试功能都会无序打印数字.

有人可以确认它们是否相同或者是否存在不同的边缘情况?是否优先使用一种技术而不是另一种?该原子文档不说,它应该只在特殊情况下使用. …

go

6
推荐指数
3
解决办法
2663
查看次数

如果两个theads同时锁定互斥锁会怎么样?

我对互斥体的工作原理感兴趣.我了解他们的目的,因为我找到的每个网站都解释了他们的所作所为,但我无法理解在这种情况下会发生什么:

有两个线程同时运行,它们试图同时锁定互斥锁.

这在单核上不会出现问题,因为这种情况永远不会发生,但在多核系统中,我认为这是一个问题.我看不出有任何方法可以防止这样的并发问题,但它们显然存在.

谢谢你的帮助

theory concurrency multithreading mutex thread-safety

4
推荐指数
2
解决办法
4563
查看次数

带有多核处理器的c ++运算符是| = atomic吗?

我目前正与另一位开发人员辩论,他向我保证以下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处理器提供了与处理器/内核之间的内存操作顺序相关的一些保证,这表明它应该是安全的......再次,我的情况似乎并非如此.经验.

由于我对这些事情没有权威性的知识,所以我很难说出我的理由,甚至不相信我是对的.

c++ concurrency multithreading atomic multiprocessing

4
推荐指数
1
解决办法
285
查看次数

当我使用x86_64 CAS指令时,只能完全锁定一个缓存行或L3缓存?

当我使用x86_64 CAS指令时LOCK CMPXCHG,即原子(读取值,比较并写回结果),此时锁定的内容:

  1. L3缓存中只有一个缓存行?(此时没有一个核心无法读取/写入L3中的此缓存行)
  2. 或L3缓存完全?(此时没有一个核心无法读取/写入L3缓存)

这是真的吗,x86_64 Intel CPU使用?

  • 独占缓存行状态(MOESI/MESIF)的1-aproach
  • 除了Exclusive之外的任何州的第二个方法

concurrency multithreading x86-64 compare-and-swap cpu-cache

3
推荐指数
1
解决办法
352
查看次数

有没有简单的方法可以提高此自旋锁功能的性能?

我正在尝试在我的代码中实现一个自旋锁,但是我基于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)

有没有办法改善这一点,使其更快?

谢谢.

c inline-assembly spinlock

2
推荐指数
1
解决办法
895
查看次数