この配列アクセス マイクロベンチマークで (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 サイトの他の関連記事を参照してください。

ホットAIツール

Undresser.AI Undress
リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover
写真から衣服を削除するオンライン AI ツール。

Undress AI Tool
脱衣画像を無料で

Clothoff.io
AI衣類リムーバー

AI Hentai Generator
AIヘンタイを無料で生成します。

人気の記事

ホットツール

メモ帳++7.3.1
使いやすく無料のコードエディター

SublimeText3 中国語版
中国語版、とても使いやすい

ゼンドスタジオ 13.0.1
強力な PHP 統合開発環境

ドリームウィーバー CS6
ビジュアル Web 開発ツール

SublimeText3 Mac版
神レベルのコード編集ソフト(SublimeText3)

ホットトピック









Go Crawler Collyのキュースレッドの問題は、Go言語でColly Crawler Libraryを使用する問題を調査します。 �...

大企業または有名なオープンソースプロジェクトによって開発されたGOのどのライブラリが開発されていますか? GOでプログラミングするとき、開発者はしばしばいくつかの一般的なニーズに遭遇します...

GO言語で構造を定義する2つの方法:VARとタイプのキーワードの違い。構造を定義するとき、GO言語はしばしば2つの異なる執筆方法を見ます:最初...

redisstreamを使用してGo言語でメッセージキューを実装する問題は、GO言語とRedisを使用することです...

Go言語での文字列印刷の違い:printlnとstring()関数を使用する効果の違いはGOにあります...

ポインター構文とviperライブラリの使用における問題への取り組みGO言語でプログラミングするとき、特にポインターの構文と使用を理解することが重要です...

GOのマップイテレーションにより、すべての値が最後の要素になるのはなぜですか? Go言語では、いくつかのインタビューの質問に直面したとき、あなたはしばしば地図に遭遇します...
