美文网首页
什么是多线程环境下的伪共享(false sharing)?

什么是多线程环境下的伪共享(false sharing)?

作者: 鹤子青云上 | 来源:发表于2023-08-31 14:22 被阅读0次

在Java中,伪共享(false sharing)是指多线程环境下,由于缓存一致性协议的影响,不同线程访问同一缓存行中的不同数据造成的性能下降现象。当多个线程同时访问不同变量,但这些变量存储在同一缓存行中时,每个线程只修改自己的变量,但由于缓存一致性协议的要求,需要将整个缓存行的数据进行更新,导致其他线程缓存的数据失效,从而影响了性能。

接下里笔者用一段简单的Java代码,来演示下伪共享的效果:

public class FalseSharingDemo implements Runnable {
    private static final int NUM_THREADS = 2;
    private static final long ITERATIONS = 500000000L;
    private static final int ARRAY_SIZE = 8;

    private static VolatileLong[] longs = new VolatileLong[ARRAY_SIZE];

    static {
        for (int i = 0; i < ARRAY_SIZE; i++) {
            longs[i] = new VolatileLong();
        }
    }

    private final int arrayIndex;

    public FalseSharingDemo(int arrayIndex) {
        this.arrayIndex = arrayIndex;
    }

    public static void main(String[] args) throws InterruptedException {
        Thread[] threads = new Thread[NUM_THREADS];

        for (int i = 0; i < NUM_THREADS; i++) {
            threads[i] = new Thread(new FalseSharingDemo(i));
        }

        for (Thread t : threads) {
            t.start();
        }

        for (Thread t : threads) {
            t.join();
        }
    }

    public void run() {
        long i = ITERATIONS + 1;
        while (--i > 0) {
            longs[arrayIndex].value = i;
        }
    }

    public static class VolatileLong {
        public volatile long value = 0L;
    }
}

在上面的示例代码中,我们创建了一个包含多个VolatileLong对象的数组。每个VolatileLong对象都包含一个volatile修饰的long类型的变量。在run()方法中,每个线程都会通过循环将自己的索引对应的VolatileLong对象的value字段设置为递减的值。

当我们运行该示例代码时,由于VolatileLong对象存储在同一缓存行中,不同线程对不同的VolatileLong对象进行操作,但由于缓存一致性协议的要求,每次写操作都会导致整个缓存行的数据失效。这将引起多个线程之间频繁的缓存行无效和更新,导致性能下降。

为了解决伪共享问题,可以使用填充(padding)技术来确保不同变量在不同的缓存行中,从而避免了不必要的缓存行无效和更新。可以通过在VolatileLong类中增加填充字段来解决伪共享问题,例如:

public static class VolatileLong {
    public volatile long value = 0L;
    public long padding1, padding2, padding3, padding4, padding5, padding6;
}

通过在VolatileLong类中添加填充字段,可以将不同的VolatileLong对象分散到不同的缓存行中,从而避免了伪共享带来的性能下降。

相关文章

  • 伪共享

    转载于 杂谈 什么是伪共享(false sharing)?[https://www.cnblogs.com/ton...

  • 伪共享-false sharing

    伪共享1. cpu与主存之间的缓存速度:1级缓存>2级缓存>3级缓存>主存2. 缓存以行为单位,每行2的幂次方个字...

  • 伪共享(false sharing)

    背景: 在对称多处理器(SMP)系统中,每个处理器都有各自的本地cache(local cache)。内存系统必须...

  • 杂谈 什么是伪共享(false sharing)?

    问题 (1)什么是 CPU 缓存行? (2)什么是内存屏障? (3)什么是伪共享? (4)如何避免伪共享? CPU...

  • 杂谈 什么是伪共享(false sharing)?

    问题 (1)什么是 CPU 缓存行? (2)什么是内存屏障? (3)什么是伪共享? (4)如何避免伪共享? CPU...

  • 伪共享(false sharing)详解

    一、什么是伪共享 CPU缓存系统中是以缓存行(cache line)为单位存储的。目前主流的CPU Cache的C...

  • Java中的伪共享(false sharing)

    维基百科中对伪共享的定义如下: 其大致意思是:CPU的缓存是以缓存行(cache line)为单位进行缓存的,当多...

  • @Contended

    表示被注解的类或/字段可能存在内存竞争,通常采用伪共享(false sharing)。此注释用作提示,此类对象和字...

  • 伪共享(False Sharing)和缓存行(Cache Lin

    前言 在上篇介绍LongAdder的文章中,我们最后留下了一个问题,为什么Cell中要插入很多个实际上并没有使用的...

  • 什么是线程安全?如何保证线程安全?基本特征

    什么是线程安全?   线程安全是一个多线程环境下正确性的概念,也就是保证多线程环境下共享的、可修改的状态的正确性,...

网友评论

      本文标题:什么是多线程环境下的伪共享(false sharing)?

      本文链接:https://www.haomeiwen.com/subject/madzmdtx.html