본문 바로가기

C#

[C#] 캐시 지역성 테스트

캐시 지역성

최근에 사용했던 데이터와 인접한 데이터가 참조될 가능성이 높다는 특성으로

캐시가 효율적으로 동작하기 위해 사용되는 성질이다.

 

 


실험 환경

Windows 10

C# 유니티 

 


실험방법

2중 for문을 돌려 인덱스 접근을 다르게 한다.

하나는 i, j / 하나는 j, i로 접근

 


i, j 반복

실험코드

using System;
using System.Collections.Generic;
using UnityEngine;

public class TimeTester : MonoBehaviour
{
    void Start()
    {
        int repeat = 5000;
        CheckTime(() =>
        {
            int[,] arr = new int[repeat, repeat];
            for (int i = 0; i < repeat; i++)
            {
                for (int j = 0; j < repeat; j++)
                {
                    arr[i, j] = 0;
                }
            }

        }, "i, j", 10);
    }

    

    private void CheckTime(Action action, string testName, int repeat)
    {
        double sum = 0;
        for (int i = 1; i <= repeat; i++)
        {
            var watch = new System.Diagnostics.Stopwatch();
            watch.Start();

            action();

            watch.Stop();
            sum += watch.ElapsedMilliseconds;

            Debug.Log(testName + "반복" + i + ": " + repeat + ", 시간: " + watch.ElapsedMilliseconds + "ms");
        }

        Debug.Log(testName + "평균: " + sum / repeat + "ms");
    }
}

j, i 반복

실험코드

using System;
using System.Collections.Generic;
using UnityEngine;

public class TimeTester : MonoBehaviour
{
    void Start()
    {
        int repeat = 5000;
        CheckTime(() =>
        {
            int[,] arr = new int[repeat, repeat];
            for (int i = 0; i < repeat; i++)
            {
                for (int j = 0; j < repeat; j++)
                {
                    arr[j, i] = 0;
                }
            }

        }, "j, i", 10);
    }

    

    private void CheckTime(Action action, string testName, int repeat)
    {
        double sum = 0;
        for (int i = 1; i <= repeat; i++)
        {
            var watch = new System.Diagnostics.Stopwatch();
            watch.Start();

            action();

            watch.Stop();
            sum += watch.ElapsedMilliseconds;

            Debug.Log(testName + "반복" + i + ": " + repeat + ", 시간: " + watch.ElapsedMilliseconds + "ms");
        }

        Debug.Log(testName + "평균: " + sum / repeat + "ms");
    }
}

결과

i, j 반복 평균: 119ms

j, i 반복 평균: 154ms

 

5000 X 5000일경우 j, i 순으로 탐색하면 계속 int * 5000사이즈만큼 떨어진 메모리를 참조하기 때문에

캐시메모리 지역성이 활용되기가 어렵다.

 


추가실험

캐시 메모리 지역성때문에 속도차이가 난다면 

배열 크기를 작게해서 실험한다면 속도가 비슷하지 않을까?

 

더보기

실험방법

배열의 크기를 2 X 2로 만들어 위와 같이 i, j 순서를 바꿔 반복시켜 본다.

 

결과

별 차이가 없다. 

배열 크기가 작아서 반대로 해도 지역성 특성을 이용할 수 있는 것 같다고 추측된다.

실험 코드

using System;
using System.Collections.Generic;
using UnityEngine;

public class TimeTester : MonoBehaviour
{
    void Start()
    {
        int repeat = 2;

        CheckTime(() =>
        {
            for (int k = 0; k < 500000; k++)
            {
                int[,] arr = new int[repeat, repeat];
                for (int i = 0; i < repeat; i++)
                {
                    for (int j = 0; j < repeat; j++)
                    {
                        arr[i, j] = 0;
                    }
                }
            }

        }, "i, j", 10);

        CheckTime(() =>
        {
            for (int k = 0; k < 500000; k++) {
                int[,] arr = new int[repeat, repeat];
                for (int i = 0; i < repeat; i++)
                {
                    for (int j = 0; j < repeat; j++)
                    {
                        arr[j, i] = 0;
                    }
                }
            }

        }, "j, i", 10);
    }

    

    private void CheckTime(Action action, string testName, int repeat)
    {
        double sum = 0;
        for (int i = 1; i <= repeat; i++)
        {
            var watch = new System.Diagnostics.Stopwatch();
            watch.Start();

            action();

            watch.Stop();
            sum += watch.ElapsedMilliseconds;

            Debug.Log(testName + "반복" + i + ": " + repeat + ", 시간: " + watch.ElapsedMilliseconds + "ms");
        }

        Debug.Log(testName + "평균: " + sum / repeat + "ms");
    }
}

 

100% 지역성 때문이다 라고 하기엔 모르는게 많아서 말하긴 어렵겠지만

어느정도 영향이 있다고 추측된다.

'C#' 카테고리의 다른 글

박싱 언박싱 성능 체크 기록  (0) 2024.01.31
[C#] Generic 함수 타입 변수로 지정하기  (0) 2023.10.25
[C#] 스택(Stack), 큐(Queue) 속도 차이  (0) 2022.06.23