概要
この記事では、32 ビット ループ カウンタを_mm_popcnt_u64 組み込み関数を使用した、パフォーマンスが重要なループ内の 64 ビット カウンター。この問題により、Intel CPU のパフォーマンスが大幅に低下し、実行速度の低下につながりました。著者は、この動作の背後にある理由を調査し、考えられる解決策を提供します。
詳細
問題のコードには、データの配列を反復処理してポップカウントを実行するループが含まれています。 x86 組み込み命令を使用した操作。ループ カウンター変数は最初は符号なし整数でしたが、これを 64 ビット符号なし整数 (uint64_t) に置き換えると、パフォーマンスが約 50% 低下しました。
原因を調査するために、作成者は次のようにコードをコンパイルしました。さまざまな最適化フラグを設定し、結果のアセンブリ コードを分析しました。彼らは、32 ビット バージョンと 64 ビット バージョンで異なるアセンブリが生成されることを観察し、コンパイラのバグを疑いました。
しかし、異なるコンパイラでコードをテストした後、作成者は問題はないと結論付けました。これはコンパイラのバグが原因ではなく、ハードウェアの誤ったデータ依存関係が原因です。 _mm_popcnt_u64 命令を Intel Sandy/Ivy Bridge および Haswell プロセッサで使用すると、宛先レジスタに対する誤った依存関係が示され、宛先の準備ができるまで命令は実行前に待機します。この誤った依存関係はループの繰り返し全体に引き継がれ、プロセッサが異なる反復を並列化できなくなり、パフォーマンスの低下につながる可能性があります。
著者は、popcount 操作を分離し、誤った依存関係を解消することでパフォーマンスの違いを実証するインライン アセンブリ テストを提示しています。鎖。これらのテストは、誤った依存関係がパフォーマンスに大きな影響を及ぼし、速度が 18.6195 GB/s から 8.49272 GB/s に低下することを示しています。
この記事では、この問題が Intel CPU に影響するのに対し、AMD プロセッサには影響することも強調しています。これは間違っていないようです
解決策
このパフォーマンスの問題を軽減するために、著者はいくつかの解決策を提案しています。
以上がIntel CPU で 32 ビット ループ カウンターを 64 ビットに置き換えると、「_mm_popcnt_u64」のパフォーマンスが低下するのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。