Julia 和其他语言中的竞争条件和原子操作

Ser*_*kov 4 multithreading atomic julia

我有几个关于原子操作和多线程的问题。

  1. 有一个函数会发生竞争条件 (julia lang):
function counter(n)
    counter = 0
    for i in 1:n
        counter += i
    end
    return counter
end
Run Code Online (Sandbox Code Playgroud)

如果使用原子操作来更改全局变量“计数器”,这是否有助于消除竞争条件?

  1. 缓存一致性协议对性能有实际影响吗?像 JVM 这样的虚拟机可以使用自己的架构来支持并行计算。

  2. 原子算术和类似的操作比普通算术需要更多还是更少的资源?

现在对我来说很难了。希望得到您的帮助。

Sim*_*ure 6

我不太明白你的例子,变量counter似乎是本地的,然后你的例子中就不会有竞争条件。

无论如何,是的,原子操作将确保不会发生竞争条件。有 2 或 3 种方法可以做到这一点。

1.您的柜台可以是Atomic{Int}

using .Threads
const counter = Atomic{Int}(0)
...
function updatecounter(i)
    atomic_add!(counter, i)
end
Run Code Online (Sandbox Code Playgroud)

手册中对此进行了描述:https ://docs.julialang.org/en/v1/manual/multi-threading/#Atomic-Operations

2.您可以在结构体中使用声明为的字段@atomic

mutable struct Counter
    @atomic c::Int
end
const counter = Counter(0)
...
function updatecounter(i)
    @atomic counter.c += i
end
Run Code Online (Sandbox Code Playgroud)

这是在这里描述的: https: //docs.julialang.org/en/v1/base/multi-threading/#Atomic-operations 似乎语义的细节还没有写出来,但它与 C++ 中的相同。

3.可以使用锁:

counter = 0
countlock = ReentrantLock()
...
function updatecounter(i)
    @lock countlock global counter += i
end
Run Code Online (Sandbox Code Playgroud)
  1. 和 2. 或多或少相同。锁定方法速度较慢,但​​如果必须串行完成多个操作,则可以使用锁定方法。不管你怎么做,相对于非原子算术都会有性能下降。1. 和 2. 中的原子原语必须执行内存栅栏以确保正确的排序,因此缓存一致性很重要,具体取决于硬件。