标签: compare-and-swap

比较和交换原子操作与负载链接/存储条件操作

在x86处理器下,我不确定比较和交换原子操作和加载链接/存储条件操作之间的区别.后者比前者更安全吗?情况是第一个比第二个好吗?

c++ atomic compare-and-swap

9
推荐指数
2
解决办法
4462
查看次数

使用OpenMP原子操作进行获取和添加

我正在使用OpenMP,需要使用fetch-and-add操作.但是,OpenMP不提供适当的指令/调用.我想保留最大的可移植性,因此我不想依赖编译器内在函数.

相反,我正在寻找一种方法来利用OpenMP的原子操作来实现这一点,但我已经走到了尽头.甚至可以这样做吗?注意,以下代码几乎可以满足我的需求:

#pragma omp atomic
x += a
Run Code Online (Sandbox Code Playgroud)

几乎 - 但不完全,因为我真的需要旧的价值x.fetch_and_add应定义为产生与以下相同的结果(仅非锁定):

template <typename T>
T fetch_and_add(volatile T& value, T increment) {
    T old;
    #pragma omp critical
    {
        old = value;
        value += increment;
    }
    return old;
}
Run Code Online (Sandbox Code Playgroud)

(如果我没有弄错的话,可以要求一个等价的问题进行比较和交换,但可以用另一个来实现.)

c++ atomic openmp compare-and-swap

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

如何:编写一个只能调用一次的线程安全方法?

我正在尝试编写一个只能调用一次的线程安全方法(每个对象实例).如果之前已调用异常,则应抛出异常.

我想出了两个解决方案.他们都是正确的吗?如果没有,他们有什么问题?

  1. lock:

    public void Foo()
    {
        lock (fooLock)
        {
            if (fooCalled) throw new InvalidOperationException();
            fooCalled = true;
        }
        …
    }
    private object fooLock = new object();
    private bool fooCalled;
    
    Run Code Online (Sandbox Code Playgroud)
  2. Interlocked.CompareExchange:

    public void Foo()
    {
        if (Interlocked.CompareExchange(ref fooCalled, 1, 0) == 1)
            throw new InvalidOperationException();
        …
    }
    private int fooCalled;
    
    Run Code Online (Sandbox Code Playgroud)

    如果我没有弄错的话,这个解决方案具有无锁的优点(在我的情况下似乎无关紧要),并且它需要更少的私有字段.

我也愿意接受合理的意见,哪些解决方案应该是首选的,并且如果有更好的方法可以提出进一步的建议.

.net c# multithreading interlocked compare-and-swap

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

在什么情况下可以做 - 虽然比在什么时候更有效?

而与之相比

块为空时,while和do-while在功能上是等效,尽管看起来更自然:

do {} while (keepLooping());
while (keepLooping()) {}
Run Code Online (Sandbox Code Playgroud)

使用空块的while/do-while的一个典型用例是使用compareAndSet(CAS)强制更新原子对象.例如,下面的代码将以a线程安全的方式递增:

int i;
AtomicInteger a = new AtomicInteger();
while (!a.compareAndSet(i = a.get(), i + 1)) {}
Run Code Online (Sandbox Code Playgroud)

上下文

java.util.concurrent的几个部分使用do {} while (...)CAS操作的惯用语和ForkJoinPool解释的javadoc :

有几种异常do {} while (!cas...)现象是强制更新CAS变量的最简单方法.

既然他们承认这是不寻常的,我认为他们意味着最好而不是最简单.

是否存在do {} while (!cas)while (!cas) {}什么原因更有效的情况?

java performance while-loop do-while compare-and-swap

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

基于CompareExchange的互锁实施是否应该使用SpinWait?

以下是基于的互锁方法的实现Interlocked.CompareExchange

这段代码SpinWait在重复之前是否宜使用自旋?

public static bool AddIfLessThan(ref int location, int value, int comparison)
{
    int currentValue;
    do
    {
        currentValue = location; // Read the current value
        if (currentValue >= comparison) return false; // If "less than comparison" is NOT satisfied, return false
    }
    // Set to currentValue+value, iff still on currentValue; reiterate if not assigned
    while (Interlocked.CompareExchange(ref location, currentValue + value, currentValue) != currentValue);
    return true; // Assigned, so return true
}
Run Code Online (Sandbox Code Playgroud)

我已经看到SpinWait在这种情况下使用过,但是我的理论是它应该是不必要的。毕竟,循环仅包含少量指令,并且总是有一个线程在进行中。

假设有两个线程竞相执行此方法,并且第一个线程立即成功执行,而第二个线程最初不做任何更改,必须重申。没有其他竞争者,第二个线程是否有可能在第二次尝试时失败 …

c# multithreading interlocked compare-and-swap spinwait

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

Java CAS操作的执行速度比C等效的快,为什么?

  • 这里我有Java和C代码尝试使用CAS进行原子增量操作.
  • 将长变量从0增加到500,000,000.
  • C:所用时间:7300ms
  • Java:拍摄时间:2083ms
  • 任何人都可以仔细检查这些结果吗?因为我简直无法相信他们.
  • 谢谢

Java代码:

import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;

public class SmallerCASTest {

    public static void main(String[] args){
        final long MAX = 500l * 1000l * 1000l;
        final AtomicLong counter = new AtomicLong(0);

        long start = System.nanoTime();
        while (true) {
            if (counter.incrementAndGet() >= MAX) {
                break;
            }
        }

        long casTime = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start);
        System.out.println("Time Taken=" + casTime + "ms");
    }

}
Run Code Online (Sandbox Code Playgroud)

C代码:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define NITER 500000000


int main (){
   long val = …
Run Code Online (Sandbox Code Playgroud)

c java concurrency compare-and-swap

7
推荐指数
2
解决办法
1231
查看次数

是否保证compareAndSwap不会因所有参与线程而失败?

假设一些"N"个线程正在尝试CAS一个AtomicInteger变量,是否保证CAS必须成功完成一个线程?

是否有可能所有"N"线程都尝试失败?

java concurrency compare-and-swap

7
推荐指数
1
解决办法
232
查看次数

为什么某些原始类型缺少Atomic版本而某些原始类型存在?

Java提供 AtomicInteger,AtomicLong等等,基本上编译成 CAS指令在硬件层面.但是,为什么这样AtomicXXX类不存在其他原始类型,如short和浮点数喜欢floatdouble

java atomic java.util.concurrent compare-and-swap

7
推荐指数
1
解决办法
1222
查看次数

比较和交换x86 - 为什么它是一个完整的屏障?

根据这个问题的答案,似乎x86上的LOCK CMPXCHG实际上会导致完全屏障.据推测,这也是Unsafe.compareAndSwapInt()引擎盖下产生的.我很难理解为什么会这样:使用MESI协议,在更新缓存行之后,CPU是否只会使其他内核上的缓存行无效,而不是耗尽执行CAS的核心的所有存储/加载缓冲区?似乎对我很浪费......

java multithreading atomic memory-barriers compare-and-swap

7
推荐指数
1
解决办法
499
查看次数

原子整数的compareandexchange()与compareandset()

在研究 AtomicInteger 时,我发现这个 API 提供了两种方法。

比较和交换

如果当前值(称为见证值)==预期值,则以原子方式将该值设置为 newValue,并具有由以下指定的记忆效应VarHandle.compareAndExchange(java.lang.Object...)

比较并设置

以原子方式将该值设置为newValue当前值value == expectedValue,并具有由 指定的记忆效应 VarHandle.compareAndSet(java.lang.Object...)

我无法理解两者之间的区别,请帮助提供合适的例子。

java atomic compare-and-swap atomicinteger java-9

7
推荐指数
1
解决办法
3441
查看次数