programing

Cortex-A9에서 TLB 효과 측정

newstyles 2023. 7. 23. 14:07

Cortex-A9에서 TLB 효과 측정

다음 논문 https://people.freebsd.org/ ~lstewart/articles/cpumemory.pdf("모든 프로그래머가 메모리에 대해 알아야 할 것")를 읽고 저자의 테스트 중 하나, 즉 TLB가 최종 실행 시간에 미치는 영향을 측정하는 것을 시도해보고 싶었습니다.

저는 코텍스-A9를 내장한 삼성 갤럭시 S3를 제작하고 있습니다.

설명서에 따르면:

  • L1(http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0388e/Chddiifa.html)에 명령 및 데이터 캐시용 마이크로 TLB가 2개 있습니다.

  • 기본 TLB는 L2(http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0388e/Chddiifa.html)에 있습니다.

  • Data micro TLB에는 32개의 항목이 있습니다(명령 micro TLB에는 32개 또는 64개의 항목이 있습니다)

  • L1' 크기 == 32KB
  • L1 캐시 라인 == 32바이트
  • L2' 크기 == 1MB

구조체 배열을 N개의 항목으로 할당하는 작은 프로그램을 작성했습니다.각 항목의 크기는 == 32바이트이므로 캐시 라인에 적합합니다.여러 번의 읽기 액세스를 수행하고 실행 시간을 측정합니다.

typedef struct {
     int elmt; // sizeof(int) == 4 bytes
     char padding[28]; // 4 + 28 = 32B == cache line size
}entry;


volatile entry ** entries = NULL;

//Allocate memory and init to 0
entries = calloc(NB_ENTRIES, sizeof(entry *));
if(entries == NULL) perror("calloc failed"); exit(1);

for(i = 0; i < NB_ENTRIES; i++)
{
      entries[i] = mmap(NULL, 4096, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
      if(entries[i] == MAP_FAILED) perror("mmap failed"); exit(1);
}

entries[LAST_ELEMENT]->elmt = -1

//Randomly access and init with random values
n = -1;
i = 0;
while(++n < NB_ENTRIES -1)
{
      //init with random value
      entries[i]->elmt = rand() % NB_ENTRIES;

      //loop till we reach the last element
      while(entries[entries[i]->elmt]->elmt != -1)
      {
            entries[i]->elmt++;
            if(entries[i]->elmt == NB_ENTRIES)
                     entries[i]->elmt = 0;
      }

       i = entries[i]->elmt;
}


gettimeofday(&tStart, NULL);
for(i = 0; i < NB_LOOPS; i++)
{
     j = 0;
     while(j != -1)
     {
          j = entries[j]->elmt
     }
}
gettimeofday(&tEnd, NULL);

time = (tEnd.tv_sec - tStart.tv_sec);
time *= 1000000;
time += tEnd.tv_usec - tStart.tv_usec;
time *= 100000
time /= (NB_ENTRIES * NBLOOPS);

fprintf(stdout, "%d %3lld.%02lld\n", NB_ENTRIES, time / 100, time % 100);

나는 NB_ENTRIES를 4에서 1024까지 다양하게 만드는 외부 루프를 가지고 있습니다.

아래 그림에서 볼 수 있듯이 NB_ENTRIES == 256개 항목에서 실행 시간이 더 깁니다.

NB_ENTRIES == 404가 되면 "메모리 부족"이 발생합니다(마이크로 TLB가 초과된 이유는 무엇입니까? 주 TLB가 초과되었습니까?).페이지 테이블을 초과했습니까?프로세스의 가상 메모리를 초과했습니까?)

4개에서 256개, 그리고 257개에서 404개의 항목에서 실제로 무슨 일이 일어나고 있는지 누가 설명해 주시겠습니까?

Effects of TLB on execution time

편집 1

제안된 것처럼, Iran membench(src 코드)와 그 이하의 결과를 실행합니다.

membench results

편집 2

다음 논문(3페이지)에서 그들은 동일한 벤치마크를 실행했습니다.하지만 다른 단계들은 그들의 플롯에서 분명하게 볼 수 있습니다. 제 경우는 아닙니다.

enter image description here

현재 그들의 결과와 설명에 따르면, 저는 단지 몇 가지를 확인할 수 있을 뿐입니다.

  • 플롯은 L1 캐시 라인 크기가 32바이트임을 확인합니다. 왜냐하면 그들이 말했듯이

"어레이 크기가 데이터 캐시 크기(32KB)를 초과하면 읽기에서 누락 [...]가 발생하기 시작합니다. 모든 읽기에서 누락이 발생할 때 변곡점이 발생합니다."

내 경우 스트라이드 == 32바이트일 때 첫 번째 변곡점이 나타납니다. - 그래프는 2차 레벨(L2) 캐시가 있음을 보여줍니다.노란색 선(1MB == L2 크기)으로 표시된다고 생각합니다. 따라서 후자 위의 두 개의 마지막 플롯은 아마도 메인 메모리(+TLB?)에 액세스하는 동안의 지연 시간을 반영합니다.

그러나 이 벤치마크에서 다음을 식별할 수 없습니다.

  • 캐시 연관성.일반적으로 D-Cache와 I-Cache는 4방향 연관성이 있습니다(Cortex-A9 TRM).
  • TLB 효과.그들이 말했듯이,

대부분의 시스템에서 대기 시간의 2차 증가는 제한된 수의 가상 변환을 물리적 변환으로 캐시하는 TLB를 나타냅니다. [...] TLB로 인한 대기 시간의 증가가 없다는 것은 [...]를 의미합니다."

큰 페이지 크기가 사용되었거나 축소되었을 수 있습니다.

EDIT 3

링크는 다른 membench 그래프의 TLB 효과를 설명합니다.제 그래프에서도 같은 효과를 얻을 수 있습니다.

4KB 페이지 시스템에서는 4K 미만의 속도로 성장하면서 각 페이지의 활용도가 점점 낮아집니다 [...]. 각 액세스에서 2단계 TLB에 액세스해야 합니다.

Cortex-A9는 4KB 페이지 모드를 지원합니다.제 그래프에서 볼 수 있듯이, 최대 발전 == 4K에 도달하면 지연 시간이 증가합니다.

당신은 실제로 전체 페이지를 건너뛰고 있기 때문에 갑자기 다시 혜택을 받기 시작합니다.

tl;dr -> 적절한 MVCE를 제공합니다.

이 답변은 댓글이어야 하지만 너무 커서 댓글로 게시할 수 없으므로 대신 답변으로 게시합니다.

  1. 구문 오류(세미콜론 누락)를 여러 개 수정하고 정의되지 않은 변수를 선언해야 했습니다.

  2. 그 문제를 그는 아무것도 . (첫이 종료되었습니다.)mmap항상 괄호를 사용하도록 팁을 주고 있습니다. 이렇게 하지 않아 발생한 첫 번째와 두 번째 오류입니다.

.

// after calloc:
if(entries == NULL) perror("calloc failed"); exit(1);
// after mmap
if(entries[i] == MAP_FAILED) perror("mmap failed"); exit(1);

두 라인 모두 상태에 상관없이 프로그램을 종료합니다.

  1. 여기에 무한 루프(재포맷, 괄호 추가, 기타 변경 없음)가 있습니다.

.

//Randomly access and init with random values
n = -1;
i = 0;
while (++n < NB_ENTRIES -1) {
    //init with random value
    entries[i]->elmt = rand() % NB_ENTRIES;

    //loop till we reach the last element
    while (entries[entries[i]->elmt]->elmt != -1) {
        entries[i]->elmt++;
        if (entries[i]->elmt == NB_ENTRIES) {
            entries[i]->elmt = 0;
        }
    }

    i = entries[i]->elmt;
}

첫 은 설을통첫번시반작복이째해를 합니다.entries[0]->elmt으로, 는 임의값으로의, 루프도때증다까니가합지달에 도달할 합니다.LAST_ELEMENT.그리고나서i 이값설즉니다됩정로으즉(,LAST_ELEMENT및 두 마커를 .) 및 두 번 루 는 마 를 덮 씁 니 어 커 다 드 엔 째 프 ▁) 니 writes ▁over ▁end-1다른 임의의 값으로.그런 다음 Ctrl+C를 누를 때까지 내부 루프에서 모드 NB_ENTRIES가 계속 증가합니다.

결론

도움이 필요한 경우 다른 내용이 아닌 최소, 완료 확인 가능한 예제를 게시합니다.

언급URL : https://stackoverflow.com/questions/30530300/measurement-of-tlb-effects-on-a-cortex-a9