Go의 데이터 지향 개미

훌륭한 기사The compiler will optimize that away를 읽고 "가장 순진한 데이터 지향 접근 방식"이 간단한 Go 코드의 성능에 어떤 영향을 미치는지 빠르게 확인하고 싶었습니다.

유형 정의



"Ant"에 8개의 필드, 4개의 int 및 4개의 문자열이 있다고 가정해 보겠습니다.

// An Ant is a struct with a few arbitrary fields.
type Ant struct {
    Field1 int
    Field2 string
    Field3 int
    Field4 string
    Field5 int
    Field6 string
    Field7 int
    Field8 string
}


여기에 제시된 숫자는 int가 8바이트이고 string 헤더가 16바이트인 64비트 시스템에 적용됩니다.



개미 군집을 나타내는 간단한 방법은 인접한 개미 조각입니다.

// An AntColony is a slice of Ants.
type AntColony []Ant




개미 군집을 나타내는 간단한 데이터 지향 방법은 각 필드의 모든 값을 자체 슬라이스로 묶는 것입니다.

// A DataOrientedAntColony is an alternative representation of
// an AntColony, where all the values of each fields are stored
// in a contiguous slice, in a data-oriented manner.
type DataOrientedAntColony struct {
    Field1 []int
    Field2 []string
    Field3 []int
    Field4 []string
    Field5 []int
    Field6 []string
    Field7 []int
    Field8 []string
}




다음은 유형 정의의 the source입니다.

벤치마크



벤치마크는 the source입니다.

(article에 설명된 대로) 병목 현상이 메모리의 데이터에 액세스하므로 주 메모리에서 더 적은 바이트를 가져오는 것이 더 빨라야 하기 때문에 일부 액세스 패턴의 경우 "데이터 지향"접근 방식이 더 빠를 것이라는 일반적인 기대가 있습니다. , 필드의 하위 집합에만 관심이 있는 경우.

개미 1,000,000마리의 경우:

  • SearchByField1: 전체 콜로니 횡단, Field1만 사용(int)
  • 내 기대: 데이터 지향이 더 빠를 것입니다.


  • SearchByField2: 전체 콜로니 횡단, Field2만 사용(문자열)
  • 내 기대: 비교할 문자열 내용에 대한 다음 포인터에 의해 시간이 지배되므로 데이터 지향이 약간 더 빠를 것입니다.


  • 검사: 전체 식민지를 횡단하고 Field1 , Field3 , Field5 , Field7를 사용합니다.
  • 내 예상: 데이터 지향은 메모리를 적게 가져오지만 서로 다른 메모리 위치에 있는 4개의 개별 슬라이스에서 가져오므로 전반적으로 느려질 것 같습니다.


  • 결과




    $ go test -bench=.
    
    cpu: Intel(R) Core(TM) i7-7600U CPU @ 2.80GHz
    
    BenchmarkAntSearchByField1-4             172       6943993 ns/op
    BenchmarkDOAntSearchByField1-4          2064        604584 ns/op
    
    BenchmarkAntSearchByField2-4             100      13402776 ns/op
    BenchmarkDOAntSearchByField2-4           244       4948108 ns/op
    
    BenchmarkAntInspect-4                     86      13767480 ns/op
    BenchmarkDOAntInspect-4                  100      10134642 ns/op
    


  • SearchByField1: 대기 시간이 무려 91%나 향상되었습니다(11배 속도 향상). 우리는 96개(8%) 중 각 Ant의 8바이트만 사용하고 있습니다. 총 시간은 가져오는 메모리의 양에 의해 좌우되며 이에 비례합니다.
  • SearchByField2: 대기 시간이 63% 향상되었습니다(3배 속도 향상). 우리는 각 Ant의 96바이트 중 16바이트(17%)만 사용하고 실제 문자열 내용에 대한 포인터를 추적합니다. 총 시간은 추가 문자열 콘텐츠 가져오기 및 비교와 상관없이 가져온 Ant 메모리의 양이 여전히 지배적입니다. 데이터 지향 버전에 대해 이렇게 빠른 속도 향상을 기대하지 않았습니다.
  • 검사: 대기 시간이 26% 향상되었습니다(1.4배 속도 향상). 우리는 96개(33%) 중 각 Ant의 32바이트를 사용하고 있습니다. 4개의 다른 슬라이스에 흩어져 있는 메모리를 처리하는 비용에 대한 내 직관은 사라졌습니다. 데이터 지향 버전이 다시 더 빨라졌습니다!

  • 결론



    단순한 데이터 지향 메모리 레이아웃은 극적인 속도 향상을 제공할 수 있습니다.

    좋은 웹페이지 즐겨찾기