【转帖】https://blog.csdn.net/weixin_33845477/article/details/89104450

アリはヒントを働くプログラマ:CPUの分岐予測を理解し、コード効率の向上

HTTPS:// blog.csdn.net/weixin_33845477/article/details/89104450 

パフォーマンスを向上させるために、ハードウェアの特性。

 


技術の普及の価値だけでなく、商用製品とも優れたプログラマー、パフォーマンスの最適化とユーザーエクスペリエンスの改善、などの効率化を強化する作業に反映するビジネス上のラインレートを、加速するオープンソース・プロジェクトによって短縮ビルドアプリケーションへの我々の道で仕事への当社の能力を強化するために、共有のヒント側面。

尾根オフアリババミドルウェア技術チームからこの記事のプログラマは、彼は、ダボプロジェクトチームのメンバーアリマイクロサービスのオープンソースプロジェクトでもあったArthasはのオンラインJavaのオープンソースプロジェクトの診断を担当しています。

まず、基本的な考え方
ダボは:3つのコア機能を提供し、軽量なオープンソースのJava RPCフレームワーク高いパフォーマンスを示します。リモートメソッド呼び出し、インテリジェントなフォールトトレランスと負荷分散、および自動登録やサービスの発見のためのインタフェース。

。B ChannelEventRunnable:すべてのネットワークイベントにダボインターフェースコールバック。

C JMHは:. Javaのマイクロベンチマークハーネスので、コードのマイクロベンチマークのために設計されたツール群です。パフォーマンスの最適化の間に分析の結果を定量化JMHを最適化するために使用されてもよいです。

第二に、需要の起源は:
スタックオーバーフローに非常によく知られている問題があります:なぜ非秩序配列よりも高速な処理の秩序配列?問題の観点から結論は、非常に重要な役割を果たしてきた分岐予測コードの効率を向上させることです。

多分合わせ今日のCPUがサポートされている分岐予測(分岐予測)と命令パイプライン(命令パイプライン)は、大幅にそれによってコード実行の効率を向上させる、CPUの効率を向上させることができます。スイッチは、本質的に指数によると、それはアドレスを取得して、アドレスアレイからジャンプすることですので、しかし、単純なジャンプが、スイッチのジャンプのためならば、CPUは、何の良い解決策ではありません。

第三に、考え、計画の前提は、
効率的なコードであることを、原則の重要な実現は、ビューのスタックオーバーフローポイントの議論の結果から、パイプラインを空にするためにCPUを避けるためである、分岐予測成功率を改善することにより、パイプラインを空にするためのCPUを減らすことができます確率。だから、ハードウェアレベルに加えて、あなたが助けにコードレベルを考慮することができれば、それは、効率的なコードに事前にCPUを決定?

第四には、プログラムが検証
ダボ判断チャネル状態でChannelEventRunnableでスイッチを。チャネルが確立されると、状況は我々は、事前にこの判決を検討することができ、その状態がChannelState.RECEIVEDで、99.9%以上です。

JMHによって確認した以下は、コードの実行効率が予め後に改善させることができるか否かを判断します。

パブリッククラスTestBenchMarks {\ tpublic列挙ChannelState {\ T \ tCONNECTED、DISCONNECTED、SENT、受信された、キャッチ\ T} \ Tステート(Scope.Benchmark)\ tpublic静的クラスExecutionPlan @ {\ T \ T @ Paramで({\ u0026quot。 1000000 \ u0026quot;})\ T \ tpublic INTサイズ、\ T \ tpublic ChannelState []状態= NULL; \ T \ T @セットアップ\ T \ tpublicボイドセットアップ(){\ T \ T \ tChannelState []の値= ChannelState .values(); \ T \ T \ tstates =新しいChannelState [サイズ]; \ T \ T \ tRandomランダム=新しいランダム(新しいDate()getTime()); \ T \ T \ tfor(int型I = 0 ; I \ u0026lt;サイズ; I ++){\ T \ T \ T \色合いnextInt =にRandom.nextInt(1000000); \ T \ T \ T \ TIF(nextInt \ u0026gt; 100){\ T \ T \ T \ T \ tstates [I] = ChannelState.RECEIVED; \ T \ T \ T \ T}他{\ T \ T \ T \ T \ tstates [I] =値[nextInt%values.length]; \ T \ T \ T \ T} \ T \ T \ T} \ T \ T} \ T} \ T @フォーク(値= 5)\ T @ベンチマーク\ T @ BenchmarkMode(Mode.Throughput)\ tpublic空隙benchSiwtch(ExecutionPlan計画ブラックホールBH){\ T \色合い結果= 0; \ T \ tfor(INT I = 0、I \ u0026lt; plan.size; ++ I){\ T \ T \ tswitch(plan.states [I]){ \ T \ T \ TCASE CONNECTED:\ T \ T \ T \ tresult + = ChannelState.CONNECTED.ordinal(); \ T \ T \ T \ tbreak; \ T \ T \ TCASE DISCONNECTED:\ T \ T \ T \ tresult + = ChannelState.DISCONNECTED.ordinal(); \ T \ T \ T \ tbreak; \ T \ T \ TCASE SENT:\ T \ T \ T \ tresult + = ChannelState.SENT.ordinal(); \ T \ T \ T \ tbreak; \ T \ T \ TCASE受付:\ T \ T \ T \ tresult + = ChannelState.RECEIVED.ordinal(); \ T \ T \ T \ tbreak; \ T \ T \ TCASEキャッチ:\ T \ T \ T \ tresult + = ChannelState.CAUGHT.ordinal(); \ T \ T \ T \ tbreak; \ T \ T \ T} \ T \ T} \ T \ tbh.consume(結果); \ T} \ T @フォーク(値= 5)\ T @ベンチマーク\ T @ BenchmarkMode(Mode.Throughput)\ tpublic空隙benchIfAndSwitch(ExecutionPlan計画、ブラックホールのBH){\ T \色合い結果= 0; \ T \ tfor(INT I = 0; I \ u0026lt; plan.size; ++ I){\ T \ T \ tChannelState状態= plan.states [I]; \ T \ T \ TIF(状態== ChannelState。受信した){\ T \ T \ T \ tresult + = ChannelState.RECEIVED.ordinal(); \ T \ T \ T}他{\ T \ T \ T \ tswitch(状態){\ T \ T \ T \ TCASE CONNECTED:\ T \ T \ T \ T \ tresult + = ChannelState.CONNECTED.ordinal(); \ T \ T \ T \ T \ tbreak; \ T \ T \ T \ TCASE SENT:\ T \ T \ T \ T \ tresult + = ChannelState.SENT.ordinal(); \ T \ T \ T \ T \ tbreak; \ T \ T \ T \ TCASE DISCONNECTED:\ T \ T \ T \ T \ tresult + = ChannelState.DISCONNECTED。序数(); \ T \ T \ T \ T \ tbreak; \ T \ T \ T \ TCASEキャッチ:\ T \ T \ T \ T \ tresult + = ChannelState.CAUGHT.ordinal(); \ T \ T \ T \ T \ tbreak; \ T \ T \ T \ T} \ T \ T \ T} \ T \ T} \ T \ tbh.consume(結果); \ T}}\ T \ T \ T \ TCASEキャッチ:\ T \ T \ T \ T \ tresult + = ChannelState.CAUGHT.ordinal(); \ T \ T \ T \ T \ tbreak; \ T \ T \ T \ T} \ T \ T \ T} \ T \ T} \ T \ tbh.consume(結果); \ T}}\ T \ T \ T \ TCASEキャッチ:\ T \ T \ T \ T \ tresult + = ChannelState.CAUGHT.ordinal(); \ T \ T \ T \ T \ tbreak; \ T \ T \ T \ T} \ T \ T \ T} \ T \ T} \ T \ tbh.consume(結果); \ T}}
検証手順:

純粋なスイッチの裁判官でbenchSiwtch、
裁判官によって事前にbenchIfAndSwitch状態がChannelState.RECEIVEDされている場合。
ベンチマーク結果は以下のとおりです。

u0026quot \もたらす。io.github.hengyunabc.jmh.TestBenchMarks.benchSiwtch \ u0026quot;: 576.745±(99.9%)6.806 OPS / S [平均](最小、平均、最大)=(490.348、576.745、618.360)、STDEV = 20.066 CI(99.9%): 569.939、583.550](正規分布を仮定)#実行し、完全な合計時間:. 00:06:48Benchmark(サイズ)モードのCNTスコアエラーUnitsTestBenchMarks.benchIfAndSwitch 1000000 61.212±1535.867 100 thrpt OPS / sTestBenchMarks.benchSiwtch 100 576.745±6.806 OPS / thrpt 1000000 sが
この技術の改良されたコード効率のほぼ3倍の性能が重要な領域に配置することができるならば理解できるが、予め定められています。

V.まとめ
スイッチのCPUは、分岐予測を行うことは困難であろう。
スイッチのコード層が、CPUをフルに活用するために分岐予測機構が設けられている場合に特定の条件が比較的高い確率を事前に決定することができるされている場合。
元のリンク表示:アリのプログラマがヒント作業を| CPUの分岐予測を理解し、コード効率の向上
----------------
免責事項:この記事はCSDNブロガー元の記事「weixin_33845477」であり、 CC 4.0 BY-SAの著作権契約書に従って、再現し、元のソースのリンクと、この文を添付してください。
オリジナルリンクします。https://blog.csdn.net/weixin_33845477/article/details/89104450

おすすめ

転載: www.cnblogs.com/jinanxiaolaohu/p/12181854.html