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

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

WBOY
WBOY앞으로
2024-02-10 08:51:09608검색

在这个数组访问微基准测试中(相对于 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으로 문의하시기 바랍니다. 삭제