当前位置: 首页> 娱乐> 明星 > 伪共享问题

伪共享问题

时间:2025/8/13 4:26:27来源:https://blog.csdn.net/m0_54187478/article/details/139232187 浏览次数:1次

伪共享(False Sharing)是指在多线程环境中,多个线程操作不同但共享同一缓存行的数据,导致不必要的缓存一致性流量,从而降低系统性能。理解和解决伪共享问题对于优化多线程程序的性能非常重要。

缓存行和伪共享的基础知识

现代处理器使用缓存来提高内存访问速度,缓存以固定大小的块(称为缓存行,通常为64字节)存储数据。处理器在访问内存时,会将整行数据加载到缓存中。

伪共享的具体表现

当多个线程操作位于同一缓存行中的不同变量时,即使这些变量彼此独立,处理器也必须在每次写操作后进行缓存一致性维护。这会导致缓存行在不同处理器核之间频繁传输,严重影响性能。

举例说明

考虑以下示例,其中两个线程分别操作两个位于同一缓存行中的变量:

public class FalseSharingExample {private static class SharedData {public volatile long a;public volatile long b;}public static void main(String[] args) throws InterruptedException {SharedData data = new SharedData();Thread thread1 = new Thread(() -> {for (int i = 0; i < 1_000_000; i++) {data.a++;}});Thread thread2 = new Thread(() -> {for (int i = 0; i < 1_000_000; i++) {data.b++;}});long start = System.nanoTime();thread1.start();thread2.start();thread1.join();thread2.join();long end = System.nanoTime();System.out.println("Duration: " + (end - start) / 1_000_000 + " ms");}
}

在这个例子中,线程1和线程2分别操作变量ab,由于这两个变量可能在同一个缓存行中,伪共享问题会导致性能下降。

解决伪共享问题

1. 通过填充变量来避免伪共享

在变量之间插入填充物,使它们占用不同的缓存行:

public class FalseSharingSolution {private static class PaddedData {public volatile long a;private long p1, p2, p3, p4, p5, p6, p7; // 填充物public volatile long b;}public static void main(String[] args) throws InterruptedException {PaddedData data = new PaddedData();Thread thread1 = new Thread(() -> {for (int i = 0; i < 1_000_000; i++) {data.a++;}});Thread thread2 = new Thread(() -> {for (int i = 0; i < 1_000_000; i++) {data.b++;}});long start = System.nanoTime();thread1.start();thread2.start();thread1.join();thread2.join();long end = System.nanoTime();System.out.println("Duration: " + (end - start) / 1_000_000 + " ms");}
}
2. 使用 @Contended 注解

@Contended 注解是 JDK 提供的一种工具,用于避免伪共享。它通过在变量之间插入填充物来确保每个变量占用不同的缓存行。需要启用 JVM 参数 -XX:-RestrictContended

import sun.misc.Contended;public class ContendedExample {@Contendedpublic static class SharedData {public volatile long a;public volatile long b;}public static void main(String[] args) throws InterruptedException {SharedData data = new SharedData();Thread thread1 = new Thread(() -> {for (int i = 0; i < 1_000_000; i++) {data.a++;}});Thread thread2 = new Thread(() -> {for (int i = 0; i < 1_000_000; i++) {data.b++;}});long start = System.nanoTime();thread1.start();thread2.start();thread1.join();thread2.join();long end = System.nanoTime();System.out.println("Duration: " + (end - start) / 1_000_000 + " ms");}
}

运行时需要加上 JVM 参数:

java -XX:-RestrictContended ContendedExample

总结

伪共享问题会导致多线程程序的性能显著下降,解决方法包括通过填充变量或使用 @Contended 注解来避免不同线程操作的变量共享同一缓存行。理解和解决伪共享问题对于优化多线程程序性能至关重要。

关键字:伪共享问题

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: