다중 스레드 환경에서 거짓 공유란 무엇입니까?

Java에서 잘못된 공유는 멀티 스레드 환경에서 캐시 일관성 프로토콜의 영향으로 인해 동일한 캐시 라인의 서로 다른 데이터에 액세스하는 서로 다른 스레드로 인해 발생하는 성능 저하를 나타냅니다. 여러 스레드가 동시에 다른 변수에 액세스하지만 이러한 변수가 동일한 캐시 라인에 저장되어 있는 경우 각 스레드는 자신의 변수만 수정하지만 캐시 일관성 프로토콜의 요구 사항으로 인해 전체 캐시 라인의 데이터를 수정해야 합니다. 업데이트되어 다른 스레드에 의해 캐시된 데이터가 무효화되어 성능에 영향을 미칩니다.

다음으로 작성자는 간단한 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 객체에는 휘발성으로 수정된 long 유형의 변수가 포함되어 있습니다. run() 메소드에서 각 스레드는 루프를 통해 자신의 인덱스에 해당하는 VolatileLong 객체의 값 필드를 감소하는 값으로 설정합니다.

샘플 코드를 실행하면 VolatileLong 개체가 동일한 캐시 라인에 저장되므로 서로 다른 스레드가 서로 다른 VolatileLong 개체에서 작동하지만 캐시 일관성 프로토콜의 요구 사항으로 인해 각 쓰기 작업은 전체 캐시 라인의 데이터를 무효화합니다. . 이로 인해 캐시 라인이 자주 무효화되고 여러 스레드 간에 업데이트가 발생하여 성능이 저하됩니다.

거짓 공유 문제를 해결하기 위해 패딩 기술을 사용하여 서로 다른 변수가 서로 다른 캐시 라인에 있도록 보장함으로써 불필요한 캐시 라인 무효화 및 업데이트를 방지할 수 있습니다. 잘못된 공유 문제는 VolatileLong 클래스에 패딩 필드를 추가하여 해결할 수 있습니다. 예를 들면 다음과 같습니다.

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

VolatileLong 클래스에 패딩 필드를 추가하면 다양한 VolatileLong 객체를 다양한 캐시 라인으로 분산시킬 수 있으므로 잘못된 공유로 인한 성능 저하를 방지할 수 있습니다.

おすすめ

転載: blog.csdn.net/cz_00001/article/details/132623258