Search
Duplicate
🥕

Cache Coherence Bottleneck (false sharing)

간단소개
팔만코딩경 컨트리뷰터
ContributorNotionAccount
주제 / 분류
CS
태그
Scrap
8 more properties
멀티 코어 CPU에서, 두 개의 코어가 같은 메모리 라인에 write 작업을 수행 할 경우 코어마다 로컬 캐시의 내용이 다르게 되어버리는 문제가 생긴다. (캐시 메모리는 코어끼리 공유하는 캐시와 코어마다의 독립적인 캐시가 레벨로 나누어진다)
이를 해결하기 위해서 하드웨어에서 Cache-Coherence(캐시 일관성)을 지원하는데, 주로 MESI Protocol 이란 방식에서 Bus Snooping 을 사용한다.
Bus Snooping을 간단히 설명하자면 캐시에 write 작업을 수행 할 때마다 다른 코어들에게 브로드캐스트 한다. 다른 코어들은 이 신호를 받고 자신의 로컬-캐시 내에 같은 주소를 들고 있다면 무효화 시키고, 무효화 시킨 라인을 사용 할 때에는 최신 데이터를 들고 있는 코어에게서 캐시간 전송으로 데이터를 받는다.
(착각할 수 있는게, 이렇게 캐시를 일관화 시키면 race condition도 해결되어야 하는것이 아닌가 싶지만, CC는 쓰기-읽기 순서를 보장하는 것이라, 명령어가 atomic하지 않다면 race condition이 발생할 수 있고 race condition은 캐시를 사용하지 않는 경우에도 발생하므로 해결되지 않는다.)
여기서 의문점이 생겼는데, 같은 캐시라인에서 두 개의 코어가 같이 write 작업을 수행한다면 Cache-Coherence를 위해 많은 비용이 들텐데, 하나의 코어가 write 하는 것 보다 느리지 않을까?
[테스트 코드(github)] 이런 느낌으로 테스트
enum { CACHE_LINE = 64, ITER_NUM = 1000000000, }; alignas(CACHE_LINE) volatile char arr[CACHE_LINE]; // Same cache-line 2-therad write thread a([&]() { for (int i = 0; i < ITER_NUM / 2; i++) { arr[0] = 1; } }); thread b([&]() { for (int i = 0; i < ITER_NUM / 2; i++) { arr[CACHE_LINE - 1] = 2; } });
C++
같은 캐시라인에 스레드 2개가 총 10억 번 write 하도록 테스트를 작성 하나는 스레드 2개가 서로 다른 캐시라인에 5억 번씩 write를 한다 스레드 1개가 10억번 write하는 경우도 추가
Intel® Core™ i7-8700K CACHE_LINE - 64byte 1. Same cache-line 2-thread write : 376430100ns 2. Different cache-line 2-thread write : 119981200ns 3. Just single-thread write : 232743700ns
C
테스트에 문제가 있을 수도 있지만, 가설이 맞는 것 같다
같은 캐시라인에 스레드 2개가 분담해 write 하면 엄청 느려진다. 그냥 하나의 스레드가 write 하는게 더 빠르다.
알고보니 이걸 false sharing 이라고 하는 모양이다 ㅡ_ㅡ;;;