이 배열 액세스 마이크로벤치마크(GCC 기준)에서 Go는 4배의 성능 손실을 겪습니다. 원인은 무엇입니까? 이 문제는 Go 언어의 런타임 메커니즘 및 컴파일러 최적화와 같은 여러 측면과 관련이 있습니다. 우선, Go 언어는 배열에 접근할 때 경계 검사 메커니즘을 사용합니다. 즉, 배열 요소에 접근할 때마다 경계 검사가 수행되므로 특정 성능 손실이 발생합니다. 둘째, Go 언어 컴파일러는 상대적으로 최적화가 약하고 배열 액세스를 잘 최적화할 수 없습니다. 또한 Go 언어의 가비지 수집 메커니즘도 성능에 일정한 영향을 미칩니다. 종합하면, 이러한 요소들이 결합되어 Go는 어레이 액세스 마이크로벤치마크에서 4배의 성능 손실을 겪게 됩니다.
저는 go의 성능 특성을 더 잘 이해하여 언제 사용해야 할지 정보를 바탕으로 선택할 수 있도록 이 마이크로벤치마크를 작성했습니다.
성능 오버헤드 관점에서 볼 때 다음은 go에 이상적인 시나리오라고 생각합니다.
그럼에도 불구하고 amd64에서는 gcc -o3
에 비해 4배의 속도 차이가 났습니다. 왜 그런 겁니까?
(셸 타이밍을 사용합니다. 매번 몇 초가 걸리므로 시작은 무시할 수 있습니다)
으아아아c 버전:
으아아아업데이트:
range
이동 속도를 2배까지 높일 수 있습니다. -march=native
将 c 速度提高了 2 倍。 (并且-mno-sse
给出编译错误,显然与-o3
호환되지 않습니다)range
필요하지 않습니다) 적어도 내가 사용한 Go 및 GCC 버전(각각 1.19.6 및 12.2.0)에서 C 프로그램과 Go 프로그램의 어셈블러 출력을 보면 가장 직접적이고 분명한 차이점은 GCC라는 것입니다. Go 컴파일러에서는 불가능한 것처럼 보이는 C 프로그램을 자동으로 벡터화합니다.
이는 또한 GCC가 특정 아키텍처를 대상으로 하지 않을 때 AVX 대신 SSE를 사용하기 때문에 성능이 4배 향상되는 이유를 잘 설명합니다. 이는 32비트 스칼라 명령이 작동 폭이 4배 더 넓다는 것을 의미합니다. 실제로 -march=native
를 추가하면 내 CPU에서 GCC 출력 AVX 코드가 생성되므로 성능이 2배 향상되었습니다.
저는 Go 컴파일러가 본질적으로 자동 벡터화를 할 수 없는지, 아니면 어떤 이유로든 버그를 일으키는 특정 프로그램인지 알려줄 만큼 Go에 익숙하지 않지만 그게 근본 원인인 것 같습니다.
위 내용은 이 어레이 액세스 마이크로벤치마크에서 Go의 성능이 4배 손실되는 원인은 무엇입니까(GCC에 비해)?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!