Cache에 대한 좀 기초적인 질문입니당 ㅜㅜ

hyper9의 이미지

안녕하세요 ~

이번엔 Cache에 대해서 궁금해서 다시 질문을 드립니다.
많이 본 말이긴 한데,,,L1 Cache와 L2 Cache의 차이가 뭔지
어떤 용도로 쓰이는지를 잘몰라서 질문을 드리려고요..

그리고 Linux 2.6.x Kernel을 사용하면서 이러한 Cache의
장점을 살려 Configuration을 한다거나 활용할 수 있는 방법은
어떤건지도 함께 질문을 드리고 싶어요...

그럼 답변 미리 감사드립니다..

정태영의 이미지

cpu 의 캐쉬는 프로그래머들에게는 완전히 감춰져 있습니다. 캐쉬를 다룰 수 있는 인스트럭션 자체가 존재하질 않죠.

이런 상황에서 운영체제가 따로 할 수 있는 일은 없습니다.

그리고 l1 캐쉬와 l2 캐쉬는... cpu 자체에 포함된 (좀 더 가까운 곳에) 캐쉬가 l1 캐쉬이구요. cpu 에서 조금은 떨어진 곳에 조금 더 많은 공간을 할당한 뒤 cpu 와 연결한 것을 l2 캐쉬라고 보시면 됩니다.

거리의 차이이고, 그 거리만큼의 속도 차이가 생기겠죠. ;)

--
오랫동안 꿈을 그리는 사람은 그 꿈을 닮아간다...

http://mytears.org ~(~_~)~
나 한줄기 바람처럼..

오랫동안 꿈을 그리는 사람은 그 꿈을 닮아간다...

http://mytears.org ~(~_~)~
나 한줄기 바람처럼..

Hyun의 이미지

사용자 모드 프로그램은 캐시를 제어할 수 없지만 커널에선 가능합니다. 캐시를 flush시킨다던지, invalidate 시킨다던지, 아예 사용하지 않는다던지(io를 위한 write through같은...) 등의 명령어 또한 아키텍쳐에서 지원이 되구요.
또한 커널의 자료구조를 보다보면 구조체 중 중간중간에 캐쉬 라인을 마춰주기위한 꽁수도 종종 보였던것 같습니다..

정태영의 이미지

말씀하셨다시피 아키텍쳐에 따라 다릅니다만 널리 쓰이고 있는 x86 아키텍쳐에서는 말씀하시는 그런 인스트럭션이 없습니다. (cache 는 사용자에게 transparent 해야한다는 신념이 있어서인지는 모르겠습니다만)

--
오랫동안 꿈을 그리는 사람은 그 꿈을 닮아간다...

http://mytears.org ~(~_~)~
나 한줄기 바람처럼..

오랫동안 꿈을 그리는 사람은 그 꿈을 닮아간다...

http://mytears.org ~(~_~)~
나 한줄기 바람처럼..

Hyun의 이미지

흠... 그렇다면 x86에서는 DMA용 메모리를 어떻게 관리하나요?

정태영의 이미지

DMA 와 CPU 캐쉬와는 상관이 없습니다. 멀티 CPU 라면 cache coherence problem 같은게 있겠지만, 싱글 CPU 상이라면 고려해야할 대상이 아닙니다. 그나마도 하드웨어 적으로 처리가 되는 내용이구요.

용어가 헷갈리신 거 같은데 캐쉬는 말 그대로 다른 느린 디바이스로의 접근을 조금 더 빠르게 해줄 수 있는 중간 매체 라고 생각하시면 됩니다. CPU와 메모리 간의 속도차이를 극복하기 위해 CPU 에 사용하는 경우엔 CPU 캐쉬겠죠. 하지만 캐쉬는 꼭 CPU 에만 있는건 아닙니다.

소프트웨어 적으로 구현하기도 하구요.

--
오랫동안 꿈을 그리는 사람은 그 꿈을 닮아간다...

http://mytears.org ~(~_~)~
나 한줄기 바람처럼..

오랫동안 꿈을 그리는 사람은 그 꿈을 닮아간다...

http://mytears.org ~(~_~)~
나 한줄기 바람처럼..

headbang의 이미지

DMA와 CPU 사이에도 cache coherence problem이 발생합니다.
DMA가 사용하는 영역은 CPU cache를 우회하는 등의 방법으로 cache coherence problem을 해결하곤 합니다.

headbang의 이미지

snoop 아닐까요?

bushi의 이미지

arm 의 경우는 사용자 모드에서도 가능합니다.
system call 로 준비되어 있습니다.
다만, 꽁수를 동원해야 합니다.

언젠가 사내 메일로 발송했던 메일 일부

> You can see such code from following url.
>
> <a href="http://anonsvn.mono-project.com/viewcvs/trunk/mono/mono/mini/mini-arm.c?view=markup
>
>" rel="nofollow">http://anonsvn.mono-project.com/viewcvs/trunk/mono/mono/mini/mini-arm.c?view=markup
>
></a> *void*
> *mono_arch_flush_icache* (guint8 *code, gint size)
> {
>     __asm __volatile (*"mov r0, %0\n"*
>             *"mov r1, %1\n"*
>             *"mov r2, %2\n"*
>             *"swi 0x9f0002       @ sys_cacheflush"*
>             : //* no outputs *//
>             : *"r"* (code), *"r"* (code + size), *"r"* (0)
>             : *"r0"*, *"r1"*, *"r3"* );
>
> }
>
>
> It might be act as you want.
>
 
ARM EABI 에서는  0x0f0002 . 잘 돌아갈런진 모르겠습니다.
 
여차저차해서 __cpuc_coherent_user_range() 매크로에 의해
arch/arm/mm/proc-xsc3.S 의 xsc3_coherent_user_range() 가 불려집니다.
L1 dcache 와 icache 를 날려버리게 됩니다.
L2 dcache 는 안건드립니다.
 
부하는 상당히 클것 같습니다.
유저모드에서 주어진 파라미터를 가지고 vma 전체를 싸그리 뒤져서 주소를 얻어냅니다.
arch/arm/kernel/traps.c 의 do_cache_op()
즉, 본래 목적은 디버깅설비. 

mono 프로젝트에서 왜 저렇게 이름지었는 지는 모르겠지만,
커널 내부적으론 I,D cache 모두 flush 합니다.
꼭 어셈코드를 사용할 필요도 없을 거라 생각합니다.
gcc4 라면
#define __NR_cacheflush 0x9f0002
#define sys_cacheflush(_addr, _size)  syscall(__NR_cacheflush, _addr, _size)

정도 ? 커널에 OABI compat 를 활성화시키지 않았다면 EABI 용 번호를 쓰면 되고.

아무튼, 인스트럭션이 존재하냐, 사용자모드에서 사용가능하냐, ... 일률적이진 않겠습니다.

덧:
아규먼트가
_start, _end, _flag
세개군요.

gcc3 로 cross-compile 에서 strongarm 에 돌린 결과입니다.

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <linux/unistd.h>
 
#define __NR_sys_cacheflush 0x9f0002
 
inline _syscall3(void, sys_cacheflush,
                unsigned long, start, unsigned long, end, unsigned long, flag);
 
int main()
{
        sys_cacheflush(0, 0, 0);
        perror("");
        return 0;
}

# ./s
Success
# 

듣보잡이었다면
Function not implemented
라고 나왔겠지요.

OTL

jachin의 이미지

L1 캐쉬는 Instruction Set Cache 와 Data Cache 로 나뉘어져 있습니다.

CPU에서 바로 접근하고 있고, 가상 주소, 가상 물리적 태그를 이용하여 캐쉬안의 정보를 읽어올 수 있습니다.

L2 캐쉬는 L1 캐쉬와 다르게 Memory Hierarchy 에 따라 상위 캐쉬에 메모리 내용을 빠르게 전달하는 데에 목적이 있습니다.

대부분의 CPU 의 경우 L1 Cache 와 L2 Cache 간에는 TLB(Translation Lookaside Buffer)라고 하는 주소테이블이 존재하고 있습니다.

가상의 주소와 실제 메모리 주소간의 연결고리를 갖추고 있는 것이지요.

PC용 CPU에서는 캐쉬의 정책을 캐쉬컨트롤러와 메모리 컨트롤러가 제어하기 때문에 별다른 설정을 안 하셔도 됩니다.

다만, 커널에서 지원하는 페이지의 크기와 페이지 제어를 할 때, 각 구조마다 특정 크기와 제어 방법을 따라야 한다는 것이 원칙입니다.
====
( - -)a 이제는 학생으로 가장한 백수가 아닌 진짜 백수가 되어야겠다.

정태영의 이미지

우선 data 와 instruction 을 위한 I/O 를 분리시켜놓은 아키텍쳐를 harvard architecture 라고 부르며, 더 많은 핀이 사용되고, 내부 구현이 복잡해지겠지만 더 나은 성능을 나타내는 것으로 알려져 있습니다.

TLB 는 virtual memory 를 사용할 때 virtual address - real address 를 변환하는 데 사용하는 (또 다른) 캐쉬입니다.

잠시 헷갈려서 몇 가지 문서를 찾아봤는데, 작은 캐쉬일 수록 read / write 를 위한 latency 가 적게 만들 수 있기 때문에 (아무래도 mux 등을 구성하는데 훨씬 복잡해질테고, 느려지긴 할 거 같네요.) 속도 / 크기 는 서로 trade off 관계에 있다고 합니다. 고로 정말 빠르고 작은 캐쉬(L1), 어느정도 빠르고 어느정도큰 캐쉬(L2), 조금 빠르고 많이 큰 캐쉬(L3) 와 같은 식의 멀티 레벨 캐쉬를 구성하는 것이라고 하네요.

위키 피디아에 있는 문서는 너무 간단하게 설명이 되어 있고, SUN 에서 나온 다음 문서에 정리가 잘 되어 있는 것 같습니다.

http://www.sun.com/blueprints/1102/817-0742.pdf

--
오랫동안 꿈을 그리는 사람은 그 꿈을 닮아간다...

http://mytears.org ~(~_~)~
나 한줄기 바람처럼..

오랫동안 꿈을 그리는 사람은 그 꿈을 닮아간다...

http://mytears.org ~(~_~)~
나 한줄기 바람처럼..

sDH8988L의 이미지


위에서 많은 분들께서 설명하셨다시피, 저도 근본적인 설명을 할까 합니다.

1) Cache가 뭐냐

Cache는 원래 Data Storage (Main Memory)와 CPU 사이에 존재하는 일종의 Memory입니다.

프로그램 수행 시에 main memory에 있는 프로그램 코드와 데이터를 이 Cache에 올려 놓고 CPU는 Cache에 있는 코드와 데이터를 이용하여 프로그램을 실행합니다.

2) Cache는 왜 필요한가

CPU의 동작 속도는 main memory의 동작 속도보다 월등히 빠릅니다. 그렇기 때문에 프로그램 코드와 데이터를 main memory에서 바로 가져와 처리할 경우 CPU는 대부분의 시간 동안 놀게 됩니다. 그러한 차이를 극복하고자 하는 것이 Cache 입니다.

3) Cache의 특성

위의 2)와 같은 목적 때문에 Cache의 동작 속도는 main memory보다 휠씬 빠르고 CPU의 동작 속도에 근접합니다. 물론, 빠르게 동작해야 한다는 특성 때문에 크기는 크게 가져갈 수 없습니다.

4) 그럼 Cache가 왜 main memory와 CPU의 속도 차이를 극복할 수 있나

이 부분을 알기 위해서는 Locality라는 개념을 알아야 합니다.

- Temporal Locality : 한 번 쓰인 코드나 데이터는 다시 쓰일 확률이 높다.
- Spatial Locality : 한 번 쓰인 코드나 데이터의 인근 코드나 데이터는 쓰일 확률이 높다.

쉽게 말해, 대부분의 프로그램들이 코드나 데이터를 재사용합니다. 그렇기 때문에 재사용될 확률이 높은 것들을 CPU에 가까운 빠른 Cache안에 넣어두면 다시 쓸 때, main memory에서 퍼와서 쓰는 것보다 훨씬 빠르게 사용할 수 있습니다.
물론, 이런 재사용이 없다면, Cache는 오히려 없어져야죠.
참고로 말하자면, Cache의 재사용률은 보통 90% 넘어갑니다.

5) L1은 뭐고 L2는 뭔가

위에서 말씀 드렸다시피, cache memory는 CPU와 main memory 사이에서 성능을 보완하는 역할을 합니다. 그런데, 이 성능 보완이 1개의 Level만으로는 힘든 경우가 종종 있습니다. CPU의 속도가 main memory에 비해서 아주 빠른 경우, 그 CPU의 속도를 따라가기 위해서 CPU의 속도에 근접하는 cache를 사용합니다. 그렇지만, 이 속도를 내기 위해서는 많은 양의 memory를 cache에 넣지 못하죠. 이때, 위에서 말씀 드린 locality의 용량이 cache의 용량을 넘어 설 때가 있습니다. 이럴 경우, 성능에 안 좋은 영향을 미치죠. 해결 방안은 좀 더 느리지만, 용량을 키울 수 있는 다른 cache를 넣은 겁니다. 이 새로운 넘은 원래 있던 cache와 main memory 간의 성능차이를 보완하는 역할을 합니다.

이때, 원래 있던 cache를 L1 (Level 1), 새로운 Cache를 L2(Level 2) cache라고 합니다.

요즘처럼, CPU와 main memory 사이의 성능차가 더 커지는 시점에서는 L3도 존재합니다. (많은 Server-Side CPU들이 L3를 On-chip에 내장합니다.)

이런 식으로 해서 CPU -> L1 -> L2 -> (L3) -> main memory -> HDD 의 memory hierarchy가 생겨나게 됩니다.

Intel CPU의 경우 L1은 32KB 정도, L2는 2MB, 4MB, 6MB 정도를 보입니다.

AMD CPU의 경우 L1은 64KB, L2는 512KB, 1MB, 2MB 정도 되죠.

정태영의 이미지

4번에 약간 더 추가로

'데이타는 연속적으로 읽혀질 확률이 높다.'

라는 사실도 인해서도 캐쉬의 효용성이 비약적으로 상승합니다. 실제로 인스트럭션의 경우 대부분 연속된 값들을 가져오게 되고, 최근 CPU 들에서는 바이트 단위 캐쉬가 아닌 라인(블럭) 단위 캐쉬(set associative cache)를 사용하기 때문에 메모리를 prefetch 하는 효과를 보이게 됩니다.

--
오랫동안 꿈을 그리는 사람은 그 꿈을 닮아간다...

http://mytears.org ~(~_~)~
나 한줄기 바람처럼..

오랫동안 꿈을 그리는 사람은 그 꿈을 닮아간다...

http://mytears.org ~(~_~)~
나 한줄기 바람처럼..

jj의 이미지

커널과는 관련없지만, 프로그래머레벨에서 캐쉬까지 고려해야 한다면, valgrind의 cache profiler가 도움이 될듯하네요.

http://valgrind.org/docs/manual/cg-manual.html#cache-sim

L1, L2레벨에서 cache hit rate를 측정해주는군요.

하지만 본인은 직접 써본적은 없다는거...ㅋ

--
콘쏠의힘

--
Life is short. damn short...

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.