ホームページ  >  記事  >  バックエンド開発  >  この配列アクセス マイクロベンチマークで (GCC と比較して) Go の 4 倍のパフォーマンス低下の原因は何ですか?

この配列アクセス マイクロベンチマークで (GCC と比較して) Go の 4 倍のパフォーマンス低下の原因は何ですか?

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 は C プログラムを自動的にベクトル化するのに対し、Go コンパイラーはこれを行うことができないようです。

これは、特定のアーキテクチャをターゲットにしていない場合、GCC は AVX ではなく SSE を使用するため、パフォーマンスが 4 倍向上する理由もよく説明しています。これは、32 ビット スカラー命令幅が動作幅の 4 倍であることを意味します。実際、-march=native を追加すると、GCC が CPU 上で AVX コードを出力するようになるため、パフォーマンスが 2 倍向上しました。

私は Go コンパイラーが本質的に自動ベクトル化を実行できないのか、それともこの特定のプログラムだけが何らかの理由でエラーを引き起こしているのかを説明できるほど Go に詳しくありませんが、それが根本的な原因のようです。

以上がこの配列アクセス マイクロベンチマークで (GCC と比較して) Go の 4 倍のパフォーマンス低下の原因は何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はstackoverflow.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。