이 어레이 액세스 마이크로벤치마크에서 Go의 성능이 4배 손실되는 원인은 무엇입니까(GCC에 비해)?

WBOY
풀어 주다: 2024-02-10 08:51:09
앞으로
614명이 탐색했습니다.

在这个数组访问微基准测试中(相对于 GCC),Go 的性能损失了 4 倍,是什么原因造成的?

이 배열 액세스 마이크로벤치마크(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호환되지 않습니다)
  • gccgo는 여기에서 gcc와 동일해 보입니다(그리고 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 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:stackoverflow.com
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
최신 이슈
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿
회사 소개 부인 성명 Sitemap
PHP 중국어 웹사이트:공공복지 온라인 PHP 교육,PHP 학습자의 빠른 성장을 도와주세요!