MTRR 정리

이성훈 2014.03.02 16:51 조회 수 : 2589

현재 CPU들은 CPU 내부에 cache가 존재합니다. cache의 존재는 다 아시겠지만 조금 정리하고 가자면, 주 메모리의 느린 성능(!) 때문에 좀 더 빠른 cache 메모리를 CPU에 두어서 wait state를 0으로 줄여 관리하면 성능이 비약적으로 높아지기 때문에 사용합니다.  

하지만 cache 메모리의 가격은 비싸기 때문에 많은 용량을 사용 할 수 없고, 주 메모리에서 cache 메모리로 데이터를 가져 올 때 일반적으로 page 단위로 가져와 사용하고 업데이트 하기 때문에 데이터의 일관성에 문제가 발생 할 수 있습니다. 이런한 문제가 있기 때문에 OS는 cache를 사용 할 메모리와 아닌 메모리를 구분하여 사용하여야 하고, cache 가능하더라도 상황에 맞게 cache 타입을 선택하여 사용하여야 합니다. 그러나 지금까지 알아 본 바로는 이러한 정보는 예전에는 BIOS에서 제공하지만 현재는 CPU에서  MTRR(Memory type range register)을 이용하여 제공한다고 합니다.

MTRR 말 그대로 메모리의 타입을 범위별로 알려주는 녀석 같은데, 정확히 어떻게 사용하는지는 모릅니다. 다만 MTRR은 현재 시스템이 알아 낸 특정 메모리 범위에 cache 종류를 제공 해주는 기능을 가지고 있다고만 알고 있습니다. 아마도 이런한 메모리의 cache 타입은 OS에서 알아서 사용 할 부분이니, 정보만 제공하는것 같고 OS도 정보만 필요한 듯 하니 먼저 cache 타입이 어떤 종류가 있는지 먼저 알아보면 이해가 더 쉬울 듯 합니다. 

wiki에서 확인되는 종류는 uncached, write-through, write-combing, write-protect, write-back 이렇게 총 5 가지이고 (http://en.wikipedia.org/wiki/Memory_type_range_register) 각각의 타입마다 cache의 동작이 다 다릅니다. 

uncached 는 말 그대로 CPU에 cache 할 수 없다는 말입니다. 

write-through는 CPU가 cache를 할 수는 있지만, 메모리의 내용을 update 할 때 cache 뿐만 아니라 주 메모리에도 업데이트를 동시에 합니다. 그래서 cache 메모리가 주 메모리와 동일하게 동작하므로 성능이 느립니다. 

write-combing은 CPU가 cache의 내용을 이용하여 작업 시 read-write 작업들을 진행하는데, 주 메모리에 접근 시 read-write를 나눠서 작업한다는 겁니다. 예를 들어 write-read-write 이렇게 작업이 진행되었다면, write-combing은 read-write-write 이렇게 작업의 순서를 변경한다는 것이죠. 물론 이렇게 하는 이유는 속도가 빨라진다는데 얼핏보기에도 데이터의 일관성에 문제가 있지 않을까 싶지만, 성능을 얻는 동시에 일관성은 조금 무시함으로 VGA와 같은 그래픽 작업에 사용한다고 합니다. 

write-protect는 느낌 상 쓰기방지 모드 즉, read에만 사용하는게 아닌가 싶지만, 제대로 확인되지 않아서 일단 넘어 갑니다.

write-back은 cache 메모리의 내용을 주 메모리로 write 시 지연하여 작업하는 방식입니다. 주 메모리에 업데이트가 느린 대신 한꺼번에 작업하기 때문에 성능이 좋아집니다. 현재 대부분의 메모리는 write-back으로 설정되어 있고, MP 프로그래밍 시 신경써야 할 부분이 바로 여기에 있습니다. 일반적으로 여러 thread를 생성하여 전역변수에 동시에 여러 thread가 접근 시 lock을 잡고 read-write 하지 않으면, 대부분의 메모리가 write-back이기 때문에 전역변수에 특정 thread가 write로 값을 업데이트 시 다른 CPU의 cache들은 변경 된 값이 업데이트 되지 않습니다. 그러나 lock을 이용하여 변수를 잡아 줄 시 다른 CPU가 전역변수에 접근 할 때 지연 된 업데이트를 하지 않고, 바로 접근하여 업데이트 해 줍니다. write-back은 이렇듯 성능은 좋지만 사용자가 구분하여 사용 하여야만 올바르게 사용 할 수 있습니다.

MTRR은 이렇게 시스템에 적재 된 메모리에 대한 cache 타입을 제공하고 dmesg에서 확인이 가능 합니다.

제 시스템의 dmesg를 확인 하였을 때 다음과 같은데,

  50 MTRR variable ranges enabled:

  51   0 base 000000000 mask F00000000 write-back

  52   1 base 100000000 mask FE0000000 write-back

  53   2 base 0E0000000 mask FE0000000 uncachable

  54   3 base 0D0000000 mask FF0000000 uncachable

  55   4 base 0CF800000 mask FFF800000 uncachable

  56   5 base 11F000000 mask FFF000000 uncachable

  57   6 base 11E800000 mask FFF800000 uncachable

  58   7 base 11E600000 mask FFFE00000 uncachable

  59   8 disabled

  60   9 disabled

  61 x86 PAT enabled: cpu 0, old 0x7040600070406, new 0x7010600070106

  62 original variable MTRRs

  63 reg 0, base: 0GB, range: 4GB, type WB

  64 reg 1, base: 4GB, range: 512MB, type WB

  65 reg 2, base: 3584MB, range: 512MB, type UC

  66 reg 3, base: 3328MB, range: 256MB, type UC

  67 reg 4, base: 3320MB, range: 8MB, type UC

  68 reg 5, base: 4592MB, range: 16MB, type UC

  69 reg 6, base: 4584MB, range: 8MB, type UC

  70 reg 7, base: 4582MB, range: 2MB, type UC

  71 total RAM covered: 3806M

  72 Found optimal setting for mtrr clean up

  73  gran_size: 64K     chunk_size: 32M     num_reg: 8      lose cover RAM: 0G

  74 New variable MTRRs

  75 reg 0, base: 0GB, range: 2GB, type WB

  76 reg 1, base: 2GB, range: 1GB, type WB

  77 reg 2, base: 3GB, range: 256MB, type WB

  78 reg 3, base: 3320MB, range: 8MB, type UC

  79 reg 4, base: 4GB, range: 512MB, type WB

  80 reg 5, base: 4582MB, range: 2MB, type UC

  81 reg 6, base: 4584MB, range: 8MB, type UC

  82 reg 7, base: 4592MB, range: 16MB, type UC


[51-60] 까지는 MTRR에서 제공 된 메모리의 cache 타입이고, 이것을 범위와 용량으로 나눠서 정리한 것이 [63-70] 까지 입니다. 그러나 OS가 좀 더 확인하여 정리 하였더니 [74-82]처럼 변경 된 내용이 출력 되었습니다. 

이렇게 정리 된 내용을 어떻게 사용 할 지는 커널 코드를 더 보지 않아 확인이 안된 상황이고, 이정도이다…. 정도로만 정리하고 넘어가야 할 듯 합니다. 

XE Login