버스 스누핑

버스 스누핑(bus snooping) 또는 버스 스니핑(bus sniffing)은 캐시(스누피 캐시)의 코히런시 컨트롤러(스누퍼)가 버스 트랜잭션을 감시하거나 스누핑하는 방식이며, 그 목적은 분산 공유 메모리 시스템에서 캐시 일관성을 유지하는 것이다. 이 방식은 1983년 라비샹카르와 굿맨이 "쓰기-한 번" 캐시 일관성이라는 이름으로 도입했다. 코히런시 컨트롤러(스누퍼)를 포함하는 캐시를 스누피 캐시라고 한다.

**작동 방식**
특정 데이터가 여러 캐시에서 공유되고 프로세서가 공유 데이터의 값을 수정할 때, 변경 사항은 데이터 복사본을 가진 다른 모든 캐시로 전파되어야 한다. 이러한 변경 전파는 시스템이 캐시 일관성을 위반하는 것을 방지한다. 데이터 변경 알림은 버스 스누핑을 통해 수행될 수 있다. 모든 스누퍼는 버스의 모든 트랜잭션을 모니터링한다. 공유 캐시 블록을 수정하는 트랜잭션이 버스에 나타나면, 모든 스누퍼는 자신의 캐시에 공유 블록의 동일한 복사본이 있는지 확인한다. 캐시에 공유 블록의 복사본이 있는 경우 해당 스누퍼는 캐시 일관성을 보장하기 위한 작업을 수행한다. 이 작업은 캐시 블록의 플러시 또는 캐시 무효화일 수 있다. 또한 캐시 일관성 프로토콜에 따라 캐시 블록 상태의 변경이 포함된다.

**스누핑 프로토콜 유형**
쓰기 작업의 로컬 복사본을 관리하는 방식에 따라 두 가지 종류의 스누핑 프로토콜이 있다.

**쓰기-무효화**
프로세서가 공유 캐시 블록에 쓸 때, 다른 캐시에 있는 모든 공유 복사본은 버스 스누핑을 통해 캐시 무효화된다. 이 방법은 데이터의 하나의 복사본만 프로세서가 독점적으로 읽고 쓸 수 있도록 보장한다. 다른 캐시에 있는 다른 모든 복사본은 무효화된다. 이것은 가장 일반적으로 사용되는 스누핑 프로토콜이다. MSI, MESI, MOSI, MOESI, MESIF 프로토콜이 이 범주에 속한다.

**쓰기-업데이트**
프로세서가 공유 캐시 블록에 쓸 때, 다른 캐시에 있는 모든 공유 복사본은 버스 스누핑을 통해 업데이트된다. 이 방법은 쓰기 데이터를 버스를 통해 모든 캐시로 브로드캐스트한다. 쓰기-무효화 프로토콜보다 더 많은 버스 트래픽을 유발한다. 이것이 이 방법이 일반적이지 않은 이유이다. 드래곤 및 파이어플라이 프로토콜이 이 범주에 속한다.

**구현**
가능한 구현 중 하나는 다음과 같다.
캐시는 세 개의 추가 비트를 가질 수 있다.- V 유효(valid)- D 더티 비트(dirty bit), 캐시의 데이터가 메모리의 데이터와 다르다는 것을 나타낸다- S 공유(shared)
각 캐시 라인은 "더티"(로컬 프로세서에 의해 업데이트됨), "유효", "무효", 또는 "공유" 상태 중 하나에 있다. 캐시 라인은 값을 포함하며, 읽거나 쓸 수 있다. 캐시 라인에 쓰는 것은 값을 변경한다. 각 값은 메인 메모리(접근이 매우 느림)에 있거나 하나 이상의 로컬 캐시(빠름)에 있다. 블록이 처음 캐시에 로드될 때 "유효"로 표시된다.
로컬 캐시의 읽기 미스 발생 시, 읽기 요청은 버스로 브로드캐스트된다. 모든 캐시 컨트롤러는 버스를 모니터링한다. 만약 그 주소를 캐시하고 있고 상태가 "더티"인 경우, 상태를 "유효"로 변경하고 요청 노드에 복사본을 보낸다. "유효" 상태는 캐시 라인이 현재 상태임을 의미한다. 로컬 쓰기 미스 발생 시(그 값을 쓰려고 시도했지만 캐시에 없음), 버스 스누핑은 다른 캐시에 있는 복사본이 "무효"로 설정되도록 보장한다. "무효"는 캐시에 복사본이 있었지만 더 이상 현재 상태가 아니라는 것을 의미한다.
예를 들어, 초기 상태는 다음과 같을 수 있다.
Tag  
S
---------------------
1111 | 00 | 1 | 0 | 0
0000 | 01 | 0 | 0 | 0
0000 | 10 | 1 | 0 | 1
0000 | 11 | 0 | 0 | 0
주소 1111 00에 쓴 후에는 다음과 같이 변경된다.
Tag  
S
---------------------
1111 | 00 | 1 | 1 | 0
0000 | 01 | 0 | 0 | 0
0000 | 10 | 1 | 0 | 1
0000 | 11 | 0 | 0 | 0
캐싱 로직은 버스를 모니터링하고 캐시된 메모리가 요청되는지 감지한다. 캐시가 더티하고 공유된 상태이며 그 메모리에 대한 요청이 버스에 있는 경우, 더티 스누핑 요소는 요청자에게 데이터를 제공한다. 그 시점에서 요청자는 데이터에 대한 책임을 지거나(데이터를 더티로 표시하거나), 메모리가 복사본을 가져와서("스나프드"되었다고 함) 두 요소는 공유 상태로 전환될 수 있다.
더티로 표시된 주소를 무효화할 때(즉, 한 캐시는 더티 주소를 가지고 있고 다른 캐시는 쓰고 있는 경우) 캐시는 그 요청을 무시한다. 새 캐시는 더티, 유효, 배타적으로 표시되며 그 캐시가 이제 그 주소에 대한 책임을 진다.

**장점**
버스 스누핑의 장점은 디렉터리 기반 코히런시 메커니즘보다 빠르다는 것이다. 디렉터리 기반 시스템에서는 공유되는 데이터가 캐시 간의 일관성을 유지하는 공통 디렉터리에 배치된다. 버스 스누핑은 일반적으로 대역폭이 충분하면 모든 트랜잭션이 모든 프로세서에서 볼 수 있는 요청/응답이므로 더 빠르다.

**단점**
버스 스누핑의 단점은 제한된 확장성이다. 캐시에 빈번한 스누핑은 프로세서로부터의 접근과 경합을 일으켜 캐시 접근 시간을 증가시키고 전력 소비를 늘릴 수 있다. 각 요청은 시스템의 모든 노드로 브로드캐스트되어야 한다. 이것은 시스템이 커질수록 (물리적 또는 논리적) 버스의 크기와 그것이 제공하는 대역폭이 커져야 함을 의미한다. 버스 스누핑은 잘 확장되지 않으므로 더 큰 캐시 일관성 NUMA (ccNUMA) 시스템은 디렉터리 기반 일관성 프로토콜을 사용하는 경향이 있다.

**스눕 필터**
특정 캐시 블록에 대해 버스 트랜잭션이 발생하면 모든 스누퍼는 버스 트랜잭션을 스누핑해야 한다. 그런 다음 스누퍼는 해당 캐시 태그를 찾아 동일한 캐시 블록이 있는지 확인한다. 대부분의 경우 잘 최적화된 병렬 프로그램은 스레드 간에 데이터를 많이 공유하지 않으므로 캐시에는 캐시 블록이 없다. 따라서 캐시 블록을 가지고 있지 않은 캐시에 대한 스누퍼에 의한 캐시 태그 조회가 일반적으로 불필요한 작업이다. 그러나 태그 조회는 프로세서에 의한 캐시 접근을 방해하고 추가적인 전력 소비를 유발한다.
불필요한 스누핑을 줄이는 한 가지 방법은 스눕 필터를 사용하는 것이다. 스눕 필터는 스누퍼가 캐시 태그를 확인해야 하는지 여부를 결정한다. 스눕 필터는 디렉터리 기반 구조이며 모든 일관성 트래픽을 모니터링하여 캐시 블록의 일관성 상태를 추적한다. 이는 스눕 필터가 캐시 블록의 복사본을 가지고 있는 캐시를 알고 있음을 의미한다. 따라서 캐시 블록의 복사본을 가지고 있지 않은 캐시가 불필요한 스누핑을 하는 것을 방지할 수 있다. 스눕 필터의 위치에 따라 세 가지 유형의 필터가 있다. 하나는 캐시 측면에 위치하며 일관성 트래픽이 공유 버스에 도달하기 전에 필터링을 수행하는 소스 필터이다. 다른 하나는 수신자 캐시에 위치하며 수신자 코어에서 불필요한 캐시 태그 조회를 방지하지만, 이 유형의 필터링은 소스에서 오는 초기 일관성 메시지를 방지하지 못한다. 마지막으로 네트워크 내 필터는 공유 버스 내부에서 동적으로 일관성 트래픽을 가지치기한다. 스눕 필터는 또한 포괄적(inclusive) 및 배타적(exclusive)으로 분류된다. 포괄적 스눕 필터는 캐시에서 캐시 블록의 존재를 추적한다. 그러나 배타적 스눕 필터는 캐시에서 캐시 블록의 부재를 모니터링한다. 즉, 포괄적 스눕 필터에서의 히트는 해당 캐시 블록이 캐시에 의해 보유되고 있음을 의미한다. 반면에 배타적 스눕 필터에서의 히트는 어떤 캐시도 요청된 캐시 블록을 가지고 있지 않음을 의미한다.

**각주**

**외부 링크**
 짐 플러스퀼릭.  중앙 집중식 공유 메모리 아키텍처.-  스눕 필터.-  캐시 컨트롤러- http://www.icsa.inf.ed.ac.uk/research/groups/hase/models/coherence/index.html- http://techpubs.sgi.com/library/tpl/cgi-bin/getdoc.cgi/0650/bks/SGI_Developer/books/T_IRIX_Prog/sgi_html/ch01.html
분류:캐시 일관성