캐시히트, 캐시미스, 바이트패딩
[ 캐시히트 ]
CPU가 값을 가져오려고 할 때 Cache에 해당하는 값이 있다면 Memory까지 가지 않고 Cache까지만 가서 값을 가져올 수 있습니다. 이 경우를 Cache Hit이라고 합니다.
[ 캐시미스 ]
반대의 경우로 CPU가 값을 가져오려고 할 때 Cache에 해당하는 값이 없다면 Memory까지 가서 값을 가져와야 합니다. 이 경우를 Cache Miss이라고 합니다. 그림은 12가 cache에 없는 경우에 메모리에서 가져오는 것을 보여주고 있습니다.
정리하자면 CPU가 데이터를 요청하여 캐시 메모리에 접근했을 때 캐시 메모리가 해당 데이터를 가지고 있다면 이를
'캐시 적중(cache hit)'이라고 부르고, 해당 데이터가 없어서 DRAM에서 가져와야 한다면 '캐시 부적중(cache miss)'라 부른다. 캐시 부적중할 경우의 처리 방법은 캐시 정책에 따라 다르며, 데이터를 읽어 오는 시점으로 사용하기도 한다.
이 때 요청한 데이터를 캐시메모리에서 찾을 확률을 적중률(hit ratio)이라고 한다.
캐시 메모리의 성능은 적중률에 의해 결정된다.
실패율은 반대로 캐시 메모리의 실패 횟수를 전체 메모리 참조 횟수로 나눈 값이며, (1 - 적중률)로 구할 수 있다.
보통 CPU는 데이터를 가져오기 위해 캐시 메모리 > 메모리 > 보조기억장치 순으로 접근한다.
- 캐시 적중일 때 : 캐시 메모리의 데이터를 CPU 레지스터에 복사한다.
- 캐시 실패/메모리 적중일 때 : 메모리의 데이터를 캐시 메모리에 복사하고, 캐시 메모리의 복제된 내용을 CPU 레지스터에 복사한다.
- 캐시, 메모리 실패일 때 : 보조 기억장치에서 필요한 데이터를 메모리에 복사한다. 메모리에 복제된 내용을 캐시 메모리에 복제한다. 캐시 메모리의 복제된 데이터를 CPU 레지스터에 복제한다.
캐시메모리에 최대한 많은 데이터를 넣는다면 CPU에 필요한 대부분의 데이터를 빠르게 얻어올 수 있겠지만, 위에서 언급했듯 캐시메모리는 용량이 적기 때문에 작업 집합의 일부만을 적재할 수 있다.
마트에서 사용할 물류 창고를 만든다고 가정해보자.
물류 창고에 마트에서 팔 수 있는 모든 종류의 물건을 최대한 많이 갖다둔다면 손님이 원하는 물건이 품절돼서 사지 못하는 일이 드물 것이다. 하지만 현실적으로 공간의 크기와 건설 비용의 제약이 있으므로 물류 창고에는 잘팔리는 물건 위주로 보관하는 것이 유리할 것이다.
캐시 메모리의 성공 여부는 참조의 지역성(Locality of reference) 원리에 달려있다.
지역성은 짧은 시간 동안 제한된 주소 공간의 일부만 참조되는 경향을 말한다.
지역성의 종류
- 시간적 지역성(temporal locality) : CPU가 한 번 참조한 데이터는 다시 참조할 가능성이 높다.
- 공간적 지역성(spatial locality) : CPU가 참조한 데이터와 인접한 데이터 역시 참조될 가능성이 높다.
- 순차적 지역성(sequential locality) : 분기가 발생하지 않는 한 명령어는 메모리에 저장된 순서대로 인출/실행된다.
지역성은 어디까지나 경향에 대한 것이므로 항상 캐시의 높은 적중률을 보장해주지는 않는다.
출처:
https://zion830.tistory.com/46
http://keepcalmswag.blogspot.com/2018/06/cache.html
[ 바이트 패딩 ]
컴파일러는 성능향상을 위해 CPU가 접근하기 쉬운 위치에 필드를 배치한다.
그러다보니 중간에 빈 공간이 들어가게 되는데 이를 바이트 패딩이라고 한다.
class Test { public: int a; //4byte char b; //1byte int c; //4byte }; |
단순하게 생각하면 int 4byte + char 1byte + int 4byte로 9byte라고 생각할 수 있다.
하지만, 결과 값을 보면 12byte라는 결과가 나온다. 이런 현상이 일어나는 이유부터 얘기하자면 바이트 패딩이라는 것 때문이다.
바이트 패딩이란 클래스나 구조체에 패딩 바이트를 추가하여 CPU 접근을 더 용이하게 해주는 것이다.
좀 더 쉽게 표현해서 1칸에 1byte인 표가 있다고 하면 아래와 같이 됩니다.
32bit는 한번에 4byte. 64bit는 한번에 8byte를 읽을 수 있으니 32bit를 예로 들면 아래와 같이 읽게 된다.
위 그림에서 보듯이 마지막 int를 읽을 때 1byte가 남게 되어 이를 처리하기 위해 CPU는 두번 일 처리를 하게 됩니다.
그러기 때문에 한번 연산에 하나의 값이 들어가게끔 패딩 바이트를 추가하게 됩니다.
위와 같이 패딩 바이트를 추가하여 한번의 연산에 하나의 값이 들어가게 되고 메모리는 더 사용하나 CPU는 한번만 일처리하게 되어 보다 빠르게 처리가 되게끔 처리하게 되는것입니다.
출처: