5.10 병렬성과 메모리 계층구조 : 캐시 일관성

Bor·2021년 12월 8일
0

컴퓨터구조

목록 보기
13/15

멀티코어 멀티프로세서는 여러 개의 프로세서가 하나의 칩 안에 들어 있는 것을 말한다.이러한 프로세서들은 공통의 실제 주소 공간을 공유한다. 공유된 데이터는 캐시를 사용할 때 새로운 문제를 야기한다. 두 개의 서로 다른 프로세서가 각자 자신의 캐시를 통하여 메모리에 접근하고 주의하지 않으면 두 개의 다른 값을 가지게된다. 아래 그림은 이 문제를 보여주고 있다. 두 개의 다른 프로세서가 같은 위치에 어떻게 두 개의 다른 값을 갖게 되는지 보여주고 있다. 이러한 문제점을 일반적으로 캐시 일관성(cash coherence) 문제라고 한다.

비공식적으로, 만약 어떤 데이터를 읽을 경우 가장 최근에 쓰인 값을 반환하려면 메모리 시스템이 일관된다고 말할 수 있다. 이러한 정의는 비록 직관적으로 동의할 수는 있지만 모호하며 극히 단순. 현실은 더욱 복잡. 단순한 정의는 메모리 시스템의 동작의 서로 다른 두 가지 관점을 포함. 두 가지 모두 올바른 공유 메모리 프로그램을 작성할 때 매우 중요하다. 일관성(coherence) 이라고 불린느 첫 번째 관점은 읽기에 의해 반환되는 값이 어떤 값인지 정의한다. 정합성(consistency)이라고 불리는 두번째 관점은 쓰여 있는 값이 읽기에 의해 언제 반환되는지를 결정한다.

첫 번째 일관성을 보자. 만약 아래와 같은 조건이라면 메모리 시스템은 일관적이다.
1. 프로세서 P가 X에 쓰기를 하고 P가 읽기를 한 경우 P의 쓰기와 읽기 사시에 어떠한 다른 프로세서도 x에 쓰기를 하지 않았다면, 항상 P에 의해 쓰인 값을 변환한다. 그러므로 위 그림에서 CPU A가 단위시간 3이후에 X의 값을 읽으려 할 때, 값 1을 보게 될 것이다.
2. 하나의 프로세서가 X에 대한 읽기를 수행 시, 만약 다른 프로세서가 이전에 X에 대한 쓰기를 한 경우 그리고 X에 대한 쓰기와 읽기 동작이 시간적으로 충분히 분리, 두 동작 사이에 X에 대한 다른 쓰기 작업이 없었다면 쓰인 값이 반환된다. 따라서 그림 CPU A가 단위시간 3에서 X에 1을 저장후 CPU B의 캐시의 값 0을 1로 바꾸는 절차가 필요하다.
3. 동일한 위치의 쓰기 동작은 순서화(serialization)된다. 동일한 위치에 두 개의 프로세서 쓰기를 수행 후 모든 프로세서에 동일한 순서로 보이게 한다. 예를 들어 CPU B가 단위 시간 3 이후에 X에 2를 저장한다면 프로세서 X의 값을 2로 읽고 나중에 1로 읽을 수는 없다.

위의 첫번째 특성은 단순히 프로그램의 순서를 유지. 이특성은 단일 프로세서에서는 항상 성립. 두번재 특성은 메모리 관점에서 일관성을 갖는다는 것이 무엇을 의미하는지에 대한 개념을 정의한다. 만약 프로세서가 계속해서 예전 값을 읽어들인다면, 확실히 메모리는 비일관적(incoherent)이라고 말할 수 있다.

쓰기 순서화(write serialization)의 필요성은 더 복잡하다 할 지라도 똑같이 중요하다. 쓰기를 순서화 하지 않은 상태에서, P1이 X에 쓰기 작업을 한 후 P2가 x에 쓰기 작업을 했다고 가정. 쓰기 순서화는 모든 프로세서가 일정 시간 지난 뒤 P2가 쓴 값을 보게 될 것을 보장. 만약 우리가 쓰기를 순서화 하지 않았다면 어떤 프로세서는 P2가 쓴 값을 먼저 보고 그 후에 P1이 쓴 값을 보게 될 수도 있고 이는 P1 값을 불확실하게 만든다. 이러한 문제점을 피하는 가장 단순한 방법은 동일한 위치에 일어나는 모든 쓰기의 작업들을 동일한 순서로 보이도록 하는 것. 이러한 특성을 쓰기 순서화라고 한다.


일관성을 유지하기 위한 기본 기법

캐시 일관성을 가진 멀티프로세서, 캐시는 데이터의 이동(migration)과 복사 기능을 제공해준다.

  • 이동: 데이터느 지역 캐시로 이동될 수 있다. 이동은 먼 곳에 위치한 공유 데이터에 접근할 때 발생하는 지연과 공유 메모리 요청에 따른 대역폭을 줄어준다.
  • 복사(replication) 공유데이터가 동시에 읽힐 때, 캐시는 지역 캐시 안에 복사본을 만든다. 복사는 공유 데이터 접근 시 대기 시간과 읽기 경쟁을 감소시킨다

이 같은 이동과 복사를 지원하는 것은 공유 데이터에 접근하는 성능에 있어서 매우 중요하기에 많은 다중 프로세서들이 캐시 일관성을 유지하기 위해 하드웨어 프로토콜을 도입하고 있다. 다중 프로세서에서 일관성을 유지하기 위한 프로토콜은 캐시 일관성 유지 프로토콜(cash coherence protocol)이라고 부른다. 캐시 일관성 유지 프로토콜을 구현하기 위한 핵심은 데이터 블록의 모든 공유 상태를 추적하는 것.

가장 널리 사용되는 캐시 일관성 유지 프로토콜은 스누핑(snooping)이다. 모든 캐시는 실제 메모리블록으로부터 데이터 복사본을 가지고 있고, 블록의 공유 상태에 대한 복사본도 가지고 있다. 그러나 중앙에서 관리되는 상태는 유지하지 않는다. 캐시들은 전송 매체 (버스 또는 네트워크)를 통하여 모두 접근 가능하다. 그리고 모든 캐시 제어기들은 버스 또는 스위치 접근에 의해 요청된 블록의 복사본을 가지고 있는지 없는지를 확인하기 위해 매체를 감시(snoop)한다.

이어서 공유 버스로 구현된 스누핑 기반 캐시 일관성을 설명! 그러나 캐시 실패를 모든 프로세서에 전파하는 어떠한 통신 매체도 스누핑 기반 일관성 기법을 구현하는데 사용가능. 이와 같이 모든 캐시에 전파하는 방식은 스누핑 프로토콜을 쉽게 구현할 수 있게 만들어 주지만 확장성을 제한.


스누핑 프로토콜

일관성을 유지하는 한 가지 방법은 프로세서가 데이터를 쓰기 전에 그 데이터에 배타적인 접근을 하는 것. 이러한 형태의 프로토콜은 쓰기 작업 시 다른 캐시에 있는 복사본들을 무효화하기에 무효화 프로토콜(write invalidate protocol) 이라고 부른다. 배타적 접근은 쓰기 작업이 일어날 때 읽기 or 쓰기가 가능한 데이터의 복사본들이 없다는 것을 보장해준다. 다른 캐시의 모든 복사본들은 무효화.

위 그림은 나중 쓰기 캐시 사용 시 스누핑 버스(snooping bus)에서 무효화 프로토콜의 한 예를 보여준다. 이 프로토콜이 어떻게 일관성을 보장해주는지 보기 위해서, 다른 프로세서의 읽기 작업 후 쓰기 작업을 고려해보자. 쓰기 작업은 배타적 접근을 요구하기에 읽기 작업을 하는 프로세서에 의해 잡혀 있는 모든 복사본들은 반드시 무효화되어야 한다. 그러므로 읽기 작업이 일어날 때, 그것은 캐시에서 실패가 되고, 캐시는 데이터의 새로운 복사본을 가져와야만 한다.

쓰기 작업에서는 쓰기 작업 프로세서가 배타적 접근을 하게 된다. 즉 다른 프로세서가 동시에 쓰는 것을 방지해야 한다. 만약 두 개의 프로세서가 동시에 같은 데이터를 스려고 시도하며느 그 둘 중 하나의 경쟁에서 이기게 되고, 다른 프로세서의 복사본은 무효화 된다. 다른 프로세서사 쓰기 작업을 완료하기 위해서는 현재 갱신된 값을 갖고 있는 데이터의 새로운 복사본을 가져와야만 한다. 그러므로 이 프로토콜은 쓰기 순서화를 따른다.

결론

빠른 프로세서와 보조를 맞추도록 메모리 시스템을 만드는데 있어서 어려움은 가장 빠른 컴퓨터나 가장 느리고 싼 컴퓨터에 쓰이는 메인 메모리, DRAM의 재료가 본질적으로 같기 때문에 생긴다.

메모리 접근이 유발하는 긴 시간 지연을 극복하는 것이 가능한 근거는 지역성의 원칙이다. 이 원칙이 맞는다는 것은 메모리계층구조의 모든 계층에서 볼 수 있다. 여러 수준의 메모리 계층 구조가 정량적인 측면에서 다르게 보이지만 동작 시에는 비슷한 전략을 사용하며 똑같은 지역성의 원칙을 적용하고 있다.

다단계 캐시는 두가지 이유 때문에 다른 최적화 기법을 귑게 쓸 수 있도록 해준다. 첫째, 하위 계층 캐시의 설계 파라미터는 1차 캐시와는 다르다. 하위 계층 캐시는 훨씬 크기 때문에 더 큰 블록 크기를 사용할 수 있다. 둘째, 하위 계층 캐시는 1차 캐시와는 달리 프로세서가 계속 사용하지 않는다는 점이다. 따라서 하위 계층 캐시가 쉬고 있을 때 앞으로 발생하게 될 실패를 막기 위해서 하위 계층 캐시가 무언가 할 수 있도록 고려할 수 있다.

다른 가능한 시도는 소프트웨어의 도움을 받는 것이다. 다양한 프로그램 변형과 하드웨어 장치를 이용하여 메모리 계층구조를 효과적으로 관리하는 것이 컴파일러 분야의 주요 연구 쟁점. 이에 관해 2개의 아이디어가 연구되고 있다. 하나의 공간적 및 시간적 지역성을 높이기 위해 프로그램을 재구성하는 것이다. 이 방식은 주요 자료구조로 큰 배열을 이용하는 순환문 중심 프로그램에 중점을 두고 있다. DGEMM과 같이 큰 선형대수 문제가 전형적인 예다. 배열에 접근하는 순환문을 재구성함으로써 지역성을 상당히 개선시킬 수 있으며 결과적으로 캐시 성능도 높일 수 있다.

다른 아이디어는 선인출(prefetching)을 하는 것이다. 선인출에서는 데이터블록이 실제로 참조되기 전에 캐시로 옮겨진다. 많은 마이크로프로세서는 소프트웨어로는 알기 어려운 접근을 예측하기 위해 하드웨어 선인출을 사용한다.

선인출 : 미래에 쓰이게 될 데이터 블록을 블록 주소를 가리키는 특별한 명령어를 사용해 캐시로 미리 가져오는 기법

세 번째 접근은 메모리 전송이 최적화된 특수한 캐시 인지(cache-aware) 명령어이다. 예를 들어6.10절에서 마이크로프로세서는 쓰기 실패 시 메모리로부터 블록의 내용을 인출하지 않는 최적화를 사용한다. 왜냐하면 프로그램은 전체 블록 쓰기를 할 것이기 때문이다. 이와 같은 최적화는 하나의 커널에 대해 메모리 전송량을 크게 줄어준다.

앞으로 보게 되겠지만 메모리 시스템은 병렬 프로세서 설계 시 중요한 설계 쟁점이 된다. 시스템 성능에 크게 영향을 미치는 메모리 계층구조의 중요성은 앞으로도 설계자와 연구자들의 주요관심사가 될 것이다.

0개의 댓글