문제

작지만 자주 사용되는 함수 개체가 있습니다.각 스레드는 자체 복사본을 갖습니다.모든 것이 정적으로 할당됩니다.복사본은 전역 또는 정적 데이터를 공유하지 않습니다.허위 공유로부터 이 객체를 보호해야 합니까?

감사합니다.편집하다:Boost.Threads를 사용하는 장난감 프로그램은 다음과 같습니다.해당 필드에 대해 허위 공유가 발생할 수 있나요? 데이터?

#include <boost/thread/thread.hpp>

struct Work {
    void operator()() {
        ++data;
    }

    int data;
};

int main() {
    boost::thread_group threads;
    for (int i = 0; i < 10; ++i)
        threads.create_thread(Work());
    threads.join_all();
}
도움이 되었습니까?

해결책

스레드 간 거짓 공유는 2개 이상의 스레드가 동일한 캐시 라인을 사용하는 경우입니다.

예::

struct Work {
    Work( int& d) : data( d ) {}
    void operator()() {
        ++data;
    }

    int& data;
};

int main() {
    int false_sharing[10] = { 0 };
    boost::thread_group threads;
    for (int i = 0; i < 10; ++i)
        threads.create_thread(Work(false_sharing[i]));
    threads.join_all();

    int no_false_sharing[10 * CACHELINE_SIZE_INTS] = { 0 };
    for (int i = 0; i < 10; ++i)
        threads.create_thread(Work(no_false_sharing[i * CACHELINE_SIZE_INTS]));
    threads.join_all();
}

첫 번째 블록의 스레드는 잘못된 공유로 인해 어려움을 겪습니다.두 번째 블록의 스레드는 그렇지 않습니다(덕분에 CACHELINE_SIZE).

스택의 데이터는 항상 다른 스레드와 '멀리' 떨어져 있습니다.(예:창 아래에서는 최소한 두 페이지 이상).

함수 개체를 정의하면 잘못된 공유가 나타날 수 있습니다. Work 힙에 생성되고 이 힙 공간은 스레드 내부에서 사용됩니다.

이로 인해 여러 가지 문제가 발생할 수 있습니다. Work 인스턴스가 인접해 있으므로 캐시 라인을 공유할 수 있습니다.

하지만 ...데이터가 외부에서 절대 터치되지 않아 불필요하게 허위 공유가 유도되기 때문에 샘플이 의미가 없습니다.

이와 같은 문제를 방지하는 가장 쉬운 방법은 '공유' 데이터를 스택에 로컬로 복사한 다음 스택 복사 작업을 수행하는 것입니다.작업이 완료되면 출력 var에 다시 복사하세요.

예:

struct Work {
    Work( int& d) : data( d ) {}
    void operator()()
    {
        int tmp = data;
        for( int i = 0; i < lengthy_op; ++i )
           ++tmp;
        data = tmp;
    }

    int& data;
};

이렇게 하면 공유와 관련된 모든 문제를 방지할 수 있습니다.

다른 팁

나는 공정한 연구를했고 거짓 공유에 대한 실버 총알 솔루션이없는 것 같습니다.여기에 제가 일어 났는지 (크리스토퍼 덕분에) : 1) 사용하지 않거나 자주 사용하지 않는 것들을 사용하여 양쪽에서 데이터를 채우십시오. 2) 데이터를 스택에 복사하고 모든 노력이 완료된 후 다시 복사하십시오. 3) 캐시 정렬 된 메모리 할당을 사용하십시오.

i '는 세부 사항에 전적으로 안전하지 않지만 여기에 나의 취임이 있습니다 :

(1) Boost create_thread가 참조를 기록하기 때문에 간소화 된 예제가 끊어졌습니다.

(2) 각 스레드에서 하나의 항목으로 vector<Work>를 사용할 경우, 또는 Othrwise가 메모리에 순차적으로 메모리에 있으면 거짓 공유가 발생합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top